Анализ разрешений доступа к почтовым ящикам при подготовке плана миграции

Освоив концепции и инструментарий, можно рассмотреть сценарий и ряд процедур, которые применяются для интерпретации выходных данных этих инструментов. Они помогут определить отношения между почтовыми ящиками, а затем построить и реализовать график миграции.

Экспорт из Exchange Administrator

При использовании для экспорта информации Exchange 5.5 Directory Service (DS) инструмент генерирует выходные данные в пяти полях (Экран 1. Экспорт Exchange Administrator). Поля Obj-Class и Directory Name - обязательная часть любого экспорта, но они не используются при оценке разрешений. Поле Obj-DistName, в котором содержится отличительное имя каталога почтового ящика, непригодно для анализа связей между почтовыми ящиками, но полезно при составлении списков пользователей, почтовые ящики которых необходимо переместить одновременно. Для анализа разрешений используются поля Primary Windows NT Account и Obj-Users.

Поле Primary Windows NT Account содержит учетную запись домена для владельца почтового ящика или основного пользователя. В поле Obj-Users приводится список всех учетных записей домена (в том числе Primary Windows NT Account и групп безопасности), которые имеют пользовательский доступ к почтовому ящику. Например, на Экране 1 приводятся записи для почтовых ящиков конференц-зала, в том числе ресурс 4311 - WO4311CONF (строка 6) и ресурс 4322 - WO4322CONF (строка 7). Первичные учетные записи домена для этих записей имеют такое же имя, как имя каталога почтового ящика (например, HQWO4311CONF). Взглянув на поля Obj-Users, можно заметить, что ресурс 4311 - единственная учетная запись, связанная с почтовым ящиком 4311, но учетная запись домена HQMCCARYW имеет такой же уровень доступа к ресурсу 4322, что и основная учетная запись. Еще две особенности поля Obj-Users: основной пользователь не всегда указан первым в списке учетной записи, а несколько имеющих доступ учетных записей разделяются символом процента (%).

Поля Primary Windows NT Account и Obj-Users могут быть пустыми или содержать ?UNKNOWN. Пустое поле обычно указывает на то, что учетная запись домена удалена; ?UNKNOWN означает, что Exchange Administrator не обнаружил соответствия между SID, извлеченным из каталога Exchange и учетной записью домена (обычно из-за того, что учетная запись или домен перестали существовать).

Отчет MBInfo

MBInfo предоставляет подробные сведения об объектах Exchange, имеющих доступ к почтовому ящику. Отчет MBInfo состоит из шести полей (Экран 2. Отчет о разрешениях MBInfo). Для анализа разрешений следует обратить внимание на поля Mailbox Display Name и Folder Permissions. В отличие от экспортного файла Exchange Administrator, в отчете MBInfo информация о каждой папке верхнего уровня в объекте mailbox размещается в отдельной строке. На Экране 2 приведены выходные данные для ресурса конференц-зала, показанного на Экране 1, и для пользователя, который предоставил другому пользователю доступ к своему почтовому ящику. В поле Folder Permissions приведены разрешения для соответствующего объекта. Это поле может содержать ссылки на группы рассылки (Distribution Group, DG) - группа ALLHANDS в строке 3 - а в некоторых случаях на удаленные почтовые ящики (как в строке 18), помимо существующих почтовых ящиков. Чтобы разделить несколько наборов разрешений, каждая пара объект-разрешение просто выделяется одинарными кавычками (').

Последнее замечание о данных MBInfo относится к способу указания разрешений. Обычно инструмент относит разрешения к одной из девяти ролей (например, Reviews, Editor), перечисленных в таблице 1. Если владелец почтового ящика предоставил специальные разрешения другой учетной записи, то эти права перечисляются отдельно, как показано в строке 21 на Экране 2.

Шесть степеней разделения

На основе выходных данных MBInfo и Exchange Administrator необходимо определить, как каждый пользователь связан с остальными через разрешения. Например, пользователь, имеющий право доступа к ресурсу 4322 конференц-зала, имеет транзитивную связь со всеми другими пользователями этого конференц-зала. Все эти пользователи должны мигрировать вместе, чтобы по-прежнему обращаться к календарю конференц-зала.

Процесс определения пользователей, почтовые ящики которых требуется перенести одновременно, похож на игру "Six Degrees of Kevin Bacon" (основанную на концепции шести степеней разделения). Игрок старается связать актера с Кевином Беконом через других актеров, которые работали вместе. Например, Бенджамин Братт играл в "Красной планете" с Кэрри-Энн Мосс, которая снималась в "Матрице" вместе с Лоренсом Фишберном, а тот в свою очередь был занят в "Мистической реке" с Кевином Беконом. Транзитивные отношения соединяют Бенджамина Братта с Кевином Беконом тремя шагами или степенями.

Предположим, нам нужно обработать выходные данные MBInfo, показанные на Экран 3. Отображение взаимосвязей почтового ящика. Чтобы построить транзитивно связанные группы, требуется сопоставить почтовые ящики в списке разрешений учетной записи с отображаемыми именами других учетных записей. Каждый участник связан с другими через предоставляемый им доступ к календарю: Бенджамин предоставляет Кэрри-Энн доступ к своему календарю, Кэрри-Энн предоставляет Лоренсу доступ к ее календарю, а Лоренс предоставляет Кевину доступ к своему календарю. Почтовые ящики всех этих людей должны переноситься вместе. Если перенести почтовые ящики только Бенджамина и Кэрри-Энн, то Лоренс не сможет получить доступ к новому календарю Кэрри-Энн. Аналогично, можно анализировать выходные данные Exchange Administrator, связывая учетные записи домена в столбцах Primary Windows NT Account и Obj-Users.

Решение проблемы - в автоматизации

Даже в малых организациях задача определения связей между учетными записями может быть чрезвычайно сложной. Чтобы автоматизировать процесс, я подготовил сценарий GBPR.vbs ("group by permissions relationship" - группировка по связям разрешений), см. Листинг 1. Сценарий может быть запущен на любой системе, в которую загружен Windows Script Host (WSH). Необходимо скопировать экспортный csv-файл или файл MBInfo.txt в ту же папку, в которой находится GBPR.vbs. Сценарий связывает отображаемое имя отдельного почтового ящика (например, столбец A на Экране 3) с отображаемым именем, приведенным в столбце Folder Permissions (например, столбец F на Экране 3), чтобы построить матрицу транзитивных связей. Аналогичная операция сопоставления выполняется при обработке экспортного csv-файла. Сценарий запускается командой

cscript gbpr.vbs mode 
infile.txt outfile.csv

где mode - mbinfo или exadmin, в зависимости от анализируемого файла. Infile.txt - имя файла, содержащего информацию о разрешениях. Outfile.csv - генерируемый сценарием csv-файл (с разделением запятыми), который содержит заголовки Group, Index, Display Name, Directory Name и Distinguished Name. Перед запуском GBPR.vbs следует убедиться, что информация экспортируется во все почтовые ящики, а не только в те, которые предоставляют разрешения другим. Даже почтовые ящики, которые не предоставляют разрешений, такие как почтовый ящик Кевина на Экране 3, могут получить разрешения от других почтовых ящиков.

На Экране 4 показан образец выходных данных после обработки файла разрешений MBInfo. В столбце Group содержится число (например, 0, 1, 2), представляющее ассоциативную группу, к которой принадлежит почтовый ящик. Почтовые ящики в группе 0 не связаны ни с какой другой группой. Номер группы, отличный от нуля, означает, что учетная запись является членом указанной группы.

Столбец Index содержит уникальный индекс, который назначается сценарием каждому почтовому ящику во входном файле; эта информация используется для отладки и проверки вывода. В процессе выполнения сценарий выводит на экран общую информацию о статусе, чтобы администратор знал, что идет обработка. Если изменить значение переменной DebugOn в заголовке сценария с false на true, то на экране отображается дополнительная информация о выполнении GBPR.vbs. Выходные данные можно перенаправить в текстовый файл и установить перекрестные ссылки на значение индекса в файле, чтобы лучше понять работу сценария.

Столбцы Display Name, Directory Name и Distinguished Name содержат соответствующую информацию о каталогах Exchange. Я часто использую отличительное имя (distinguished name - DN) в сочетании с LDAP-ориентированными инструментами, чтобы строить группы распределения или входные файлы для инструментов миграции.

Изображение на Экран 4. Файл разрешений MBInfo получено на реальном сайте Exchange, содержащем более 4400 почтовых ящиков. Сценарий обнаружил 40 групп, связанных разрешениями. Некоторые группы содержали лишь двух или трех членов, а более 1900 человек не имели связей. Но одна группа связывала 2531 человека через группу централизованных конференц-залов. Номера групп - отправная точка для объединения почтовых ящиков в целях миграции. Чтобы составить график миграции, моя команда администраторов использовала выходные данные GBPR.vbs. Выяснилось, что предстоит перенести 36 групп. Мы определили, что можем перенести около 200 почтовых ящиков в день. За исключением одной очень большой группы, в каждой из остальных групп насчитывалось менее 200 членов. Из-за малых размеров некоторых групп их приходилось объединять, чтобы достичь заданного показателя 200 почтовых ящиков в день.

Совершенствуя процесс миграции, мы добавили некоторые из 1900 несвязанных почтовых ящиков к другим группам. Это не отразилось на возможностях пользователей обращаться к другим почтовым ящикам.

Сложной проблемой была миграция большой группы, в которую входило больше ящиков, чем можно перенести за один день. Обработка этой группы была отложена до последнего этапа миграции. Доступ к коллегам в процессе миграции важнее доступа к конференц-залам, поэтому данная группа была разбита на подгруппы по производственным и бизнес-подразделениям. Сотрудники службы поддержки получили доступ к почтовым ящикам, чтобы техники могли временно выделять сотрудникам ресурсы.

Иногда GBPR.vbs обнаруживает группу, в которую входят почти все почтовые ящики. Во врезке "Сведения о GBPR.vbs" объясняется, как обойти эту проблему, и приводятся другие соображения по использованию сценария.

Готовимся к миграции

Миграция в крупной организации не бывает простой. Лучшие проекты отличаются гибкостью и динамичностью. Чтобы составить план, необходимо понимать, как работает организация. С помощью методов и инструментов, описанных в данной статье, администратор может подготовить логичный график и успешно провести миграцию.

Джозеф Нойбауэр (jneubauer@windowsitpro.com) - старший системный инженер и технолог, занимается обслуживанием федеральных служб США. Специализируется на системах связи и обработки сообщений.


Сведения о GBPR.vbs

Сценарий GBPR.vbs группирует почтовые ящики в соответствии со связями, которые формируются разрешениями, предоставленными обладателями почтовых ящиков другим пользователям и почтовым ящикам. Одна из возможных проблем заключается в том, что любые два человека в организации могут быть связаны через транзитивные отношения. Сравнивая связи в крупных организациях, сценарий генерирует огромную матрицу отношений, и иногда ему не хватает памяти на этапе выполнения. Обычно эту проблему можно устранить, запустив сценарий на компьютере с памятью большей емкости. На очень больших сайтах я запускал сценарий на сервере с памятью объемом в 2 Гбайт.

Чтобы предотвратить возникновение этой проблемы, можно установить ограничение на разрешения, учитываемые сценарием при определении связей. В Листинге A показан фрагмент сценария GBPR.vbs, в котором определяется, какие роли следует рассматривать при анализе файла MBInfo. Чтобы изъять роли из рассмотрения, достаточно обозначить выделенные строки как комментарии. В приведенном фрагменте из анализа исключены роли Reviewer, Contributor и Non-editing Author. Если нужно учесть одну из этих ролей, следует просто удалить символ (') в начале соответствующей строки. Если требуется исключить из рассмотрения одну из ролей, можно добавить одинарные кавычки и превратить строку в комментарий.

В результате запуска сценария с исключенными ролями, как показано в Листинге A, на сайте с 4400 почтовыми ящиками было обнаружено 40 групп, в самой большой из которых насчитывалось 1700 членов. При запуске сценария со всеми ролями было выделено 36 групп, самая крупная из которых состояла из 2531 члена.

Еще один способ управлять размером групп и требованиями к обработке - ограничить число обрабатываемых почтовых ящиков. Обычно разрешения предоставляются внутри границ сайта, поэтому сценарий следует запускать последовательно на разных сайтах.

Как отмечалось в основной статье, в выходных данных Exchange Administrator могут присутствовать группы безопасности домена в полях Primary Windows NT Account и Obj-Users, а пары объект-разрешения в выводе MBInfo часто содержат доменные группы распределения (DG). GBPR.vbs не обрабатывает отношения, в которых участвуют разрешения, назначенные группам. Если требуется проанализировать группы, нужно изменить сценарий, чтобы расширить членство в группах, прежде чем приступать к обработке отношений.

GBPR.vbs не учитывает специальные наборы разрешений. Число вариантов специальных разрешений в выходных данных MBInfo слишком велико, чтобы сценарий проверил каждую комбинацию, поэтому рассматриваются только стандартные профили разрешений, перечисленные в таблице 1 (см. основную статью).

Листинг A. Раздел pList сценария GBPR.vbs
 ' pList.Add "reviewer", 1
 ' pList.Add "contributor", 1
 ' pList.Add "noneditingauthor", 1
 pList.Add "author", 1
 pList.Add "publishingauthor", 1
 pList.Add "editor", 1
 pList.Add "publishingeditor", 1
 pList.Add "all", 1

Листинг 1. Сценарий GBPR.vbs
' GBPR.vbs   (Group by Permissions Relationships)
'
' Joe Neubauer January 2005
'
' This script takes an Exchange Export file or the Permissions Output from MBInfo version 3.0
'   and groups mailboxes based on their permissions relationships
'
'  e.g. If Debbie grants Mary access to her mailbox, and Mary grants Stacey access to her mailbox
'       this script will determine that Debbie, Mary and Stacey should be in the same migration group
'
' When using this script with an Exchange admin export, the following fields must be in the export file
' the fields must be in this order, and they must be seprated by commas
'
'     Obj-Class,Directory Name,Obj_Dist-Name,Primary Windows NT Account,Obj-Users
'
'   The script also assumes that the directory is "clean" e.g. the script will fail if
'       the Primary Windows NT Account fields is blank
'
'
'=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
 
  bDebugOn = False       ' Set this to True to have additional info Output to the screen
 
  set objArguments = WScript.Arguments
  if objArguments.Count < 3  then
    wscript.echo "Usage: cscript GBPR.vbs MODE infile.txt outfile.csv"
    wscript.echo "  Where MODE is MBINFO if processing an MBInfo v3 output file or"
    wscript.echo "                EXADMIN if processing an Exchange Admin Export CSV file"
    wscript.echo "                        with the followng fields (in this order)"
    wscript.echo "                        Obj-Class,Directory Name,Obj_Dist-Name,Primary Windows NT Account,Obj-Users"
 
  else
    sMode = ucase(objArguments(0))               ' Used to know how to process
    sINFileName = objArguments(1)                 ' MBINFO or CSV File
    sOUTFileName = objArguments(2)                 ' Output file that will contain grouping inforation
 
    Set FileSys = CreateObject("Scripting.FileSystemObject")     ' Object to allow access to the file system
    Set NameToNumber = CreateObject("Scripting.Dictionary")     ' Converts a disp anme or account name to an index number
    Set NumberToName = CreateObject("Scripting.Dictionary")     ' Converts an index number to a disp anme or account name
    Set NumberToDDN = CreateObject("Scripting.Dictionary")     ' stores the directory name and distinguished name
    Set Relationships = CreateObject("Scripting.Dictionary")     ' Stores the mailboxes with access
    Set Groups = CreateObject("Scripting.Dictionary")      ' Stores the index numbers of the mailboxes that are related by access
    Set PList = CreateObject("Scripting.Dictionary")      ' A list of permissions that will be considered when processing MBINFO
    Set LinkedAccounts = CreateObject("Scripting.Dictionary")     ' A workspace used to convert display names to index numbers
 
 
    if sMODE = "MBINFO" then
       ' These values apply when processing MBInfo files
       bMBINFO = True
       sDataSplit = chr(9)        ' Tab Character
       sPermissionsSplit = "''"
       iPrimaryField = 0
       iPermissionsField = 5
 
       ' Comment out any permissions that you don't want to be considered when processing MBInfo files.
       ' Warning - Increasing the number of permissions considered significantly increases the
       '           relationships between accounts.  Too many account relationships in one group
       '           can cause an Out of Memory condition.  Run the script on a system with more memory.
       '           Suggested permissions to exclude are reviewer, contributer and noneditingauthor
       '           
       pList.Add "reviewer", 1
       pList.Add "contributor", 1
       pList.Add "noneditingauthor", 1
       pList.Add "author", 1
       pList.Add "publishingauthor", 1
       pList.Add "editor", 1
       pList.Add "publishingeditor", 1
       pList.Add "all", 1
    else
       ' These values apply when processing Exchange Admin Export (CSV) files
       sDataSplit = ","            ' Change this if you are not using CSV files
       sPermissionsSplit = "%"         ' Change this if you are using a different multivalued separator
       iPrimaryField = 3
       iPermissionsField = 4
       bMBINFO = False
    end if
 
    Set INFileObj = FileSys.OpenTextFile(sINFileName, 1)      ' For reading
    Set OUTFileObj = FileSys.OpenTextFile(sOUTFileName, 2, True)     ' For writing, overwrite and/or create
 
    iLineCount = 0
    iUnique = 0
    bFirstLine = True
    ' read all of the data in and consolidate mailbox permissions in to one list per mailbox
    wscript.echo "Reading Permissions Relationships..."
    do while INFileObj.AtEndOfStream <> True
      sInfo = INFileObj.ReadLine
      if bFirstLine Then
        bFirstLine = False               ' Bleed off the header line
      else
        iLineCount = iLineCount + 1
        aFields = split(sInfo,sDataSplit)         ' split text string into fields
        sMailbox = lcase(aFields(iPrimaryField))
                ' If MBINFO then data and format is Display Name
          ' Zioga, Mark     
                ' If EXADMIN then data format is Account
          ' ADALPER
        sPermissions = lcase(aFields(iPermissionsField))
                ' If MBINFO then data format is object: Access
          ' ' Default: None'' Bridge, Norman L: Reviewer'' Molsen, Justis A: Reviewer'' Kinsey, Vick S: Reviewer'
                ' If EXADMIN then data format is Account%Account%Account%Account
          ' ADALPER%ADMOODY
 
        If NameToNumber.Exists(sMailbox) Then 
          ' MBINfo may have multi lines so add each one
           Relationships(cstr(iUnique)) = Relationships(cstr(iUnique)) & sPermissions
        else
           iUnique = iUnique + 1
           NameToNumber.Add sMailbox, iUnique
           NumberToName.Add cstr(iUnique), sMailbox
           NumberToDDN.Add cstr(iUnique), aFields(1) & "," & aFields(2)    ' Directory Name , Distinguished Name
           Groups.Add cstr(iUnique), 0
           Relationships.Add cstr(iUnique), sPermissions
        End If
      End If
    loop
    if bDebugOn Then
     ''DEBUG-OUTPUT--
     For each iBox in Relationships
        Wscript.echo iBox & " - " & NumberToName(iBox) & ": " & Relationships(iBox)
     Next
     wscript.echo "-------------"
    ENd If
 
 
    ' Convert the names in the permissions list to numbers referenced by the unique IDs assigned to each mailbox
    wscript.echo "Building Relational Mapping..."
    for each iBox in Relationships
        if bMBINFO Then sPermissions = "'" & Relationships(iBox) & "'"       ' This makes it easier to parse the line
                                              ' Ignore the 0th and last elements
        LinkedAccounts.RemoveAll
        aPermList = split(sPermissions,sPermissionsSplit)
              'Exadmin format is ADALPER%ADMOODY%ADBLAND
              'MBINFO format is '' Bridge, Norman L: Reviewer'' Molsen, Justis A: Reviewer''
 
        if bMBINFo Then
          for i = 1 to ubound(aPermList) - 1       ' Ignore the 0th and last elements
            aBoxInfo = split(trim(aPermList(i)),": ")            ' Bridge, Norman L: Reviewer
 
            ' Only add the names for permissions to be considered (i.e. those in PLIST)
            if PLIST.Exists(aBoxInfo(1)) Then
              if NameToNumber.Exists(aBoxInfo(0)) Then
                 If Not(LInkedAccounts.Exists(NameToNumber(aBoxInfo(0)))) Then LinkedAccounts.Add NameToNumber(aBoxInfo(0)), "1"
              end if
            end if
          next
        else
          for i = 0 to ubound(aPermList)
            if NameToNumber.Exists(aPermList(i)) Then
               If Not(LInkedAccounts.Exists(NameToNumber(aPermList(i)))) Then LinkedAccounts.Add NameToNumber(aPermList(i)), "1"
            end if
          next
        end if
        If LInkedAccounts.Count > 0 Then
          aLinks = LInkedAccounts.Keys    ' Get all of the index IDs for people that are linked
          sRel = Join(aLInks,"~")     ' Convert the array to a text string for easier storage
        else
          sRel = ""           ' No linked accounts, I guess he's got no friends :-(
        End If
        Relationships(iBox) = sRel
    next
 
    if bDebugOn Then
     ''DEBUG-OUTPUT--
     For each iBox in Relationships
        Wscript.echo iBox & ": " & Relationships(iBox)
     Next
     wscript.echo "-------------"
    ENd If
 
    wscript.echo "Add reverse relationships..."
    ' Make sure there are forward and reverse refrences in the permissions chains
    for each iBox in Relationships
      sPermissions = Relationships(iBox)         ' Get the list of people I've granted permissions
      if sPermissions <> "" Then
        aPermList = split(sPermissions,"~")
        for i = 0 to ubound(aPermList)
          sLinked = Relationships(aPermList(i))      ' Get their permissions lists; add me if I'm not in the list
          if sLinked = "" Then                '    to build a reverse relationship
            Relationships(aPermList(i)) = cstr(iBox)
          else
            sTarget = "~" & sLinked & "~"
            sBullet = "~" & cstr(iBox) & "~"
            if Instr(sTarget,sBullet) = 0 Then 
              Relationships(aPermList(i)) = sLinked & "~" & cstr(iBox)
            End If
          End If
        next
      End If
    next
    if bDebugOn Then
     ''DEBUG-OUTPUT--
     For each iBox in Relationships
        Wscript.echo iBox & ": " & Relationships(iBox)
     Next
     wscript.echo "-------------"
    ENd If
 
    wscript.echo "Determining Relational Groups..."
    iGroupSet = 1
    for each iBox in Relationships
      bGroupMembers = TraceGroup(iBox, iGroupSet, False, 0)
      if bGroupMembers Then iGroupSet = iGroupSet + 1       ' group count increments only if two or 
                                     ' more people were linked
    Next
 
    wscript.echo "------------------------------"
    wscript.echo "Lines Read: " & iLineCount
    wscript.echo "Unique Mailboxes: " & NameToNumber.Count
    wscript.echo "Groups: " & iGroupSet
    wscript.echo "------------------------------"
    
    ' Create a CSV Output file.
    OUTFIleObj.Write "Group,Index,Display Name,DirectoryName,DistinguishedName" & chr(13) & chr(10)
    for each mbx in Groups
      OUTFIleObj.Write Groups(mbx) & "," & mbx & "," & chr(34) & NumberToName(mbx) & chr(34) & "," & NumbertoDDN(mbx) & chr(13) & chr(10)
    next 
    INFileObj.close
    Set INFileObj = nothing
  end if
 
 
Function TraceGroup(iBox, iGroupNumber, bSetState, iRecursionLevel)
   Dim bSetReturn    ' Return flag used to increment group numbering
   Dim sOthers       ' String of linked mailboxes
   Dim aOthers       ' Array of linked mailboxes
   Dim bDontCare     ' Dummy variable needed to make this a function
   Dim i      ' Counter variable
 
   bSetReturn = bSetState
   sOthers = Relationships(iBox)    ' Get the list of linked accounts
   if sOthers <> "" Then      ' Only process linked accounts
     if sOthers = iBox Then      ' Don't recursively process current account else LOOP!!
       wscript.echo "!!ERROR: Related to myself !! " & iBox & ": " & NumbertoName(iBox)
     else
       Relationships(iBox) = ""        ' Blank out my relationships so no one else processes them
       Groups(iBox) = iGroupNumber  ' Set mailbox to be part of the current group
       aOthers = split(sOthers,"~")     ' Turn the association string in to a list and recursvely process the list
       for i = 0 to ubound(aOthers)
         bDontcare = TraceGroup (cstr(aOthers(i)), iGroupNumber, True, iRecursionLevel+1)
       next
       bSetReturn = True  ' returns true since at least one relationship - else we would not be in this part of the routine
                          ' this causes group counter to intement at main routine
     end if
   end if
   TraceGroup = bSetReturn
End Function

Таблица 1. Разрешения доступа и роли
РазрешенияОписание разрешений Роль
OwnerPublishing Editor EditorPublishing Author AuthorNon-Editing Author ReviewerCont-ributorNone
Create Items Отправка сообщений в папкуxxxxxx x 
Read Items Чтение сообщений в папкеxxxxxxx  
Create Subfolders Создание дочерних папокxx x     
Edit Items Все либо созданные владельцем сообщения могут редактироватьсяxxxСозданные владельцем Созданные владельцем     
Delete Items Все либо созданные владельцем сообщения могут удалятьсяxxxСозданные владельцем Созданные владельцем     
Folder Visible Сокрытие подпапок от владельца ролиxxxxxxx  
Folder Contact Получение автоуведомлений или запросов на доступ от других пользователей. В основном для общих папокx        
Folder Owner Установка разрешений на папкуx