- NAME
- SYNOPSIS
- DESCRIPTION
  - Overview
  - Usage Notes
- ARGUMENTS
  - -c[fg] cfg_file
  - -g[roups] group[,group2,...]
  - -o[wners] user[,user2,...]
  - -i[gnore]
  - -b2
  - -s[erver] ldap_server
  - -p[ort] ldap_port
  - -d[ebug]
  - -D[EBUG]
  - -n[oop]
  - -h[elp]|-man
- EXAMPLES
  - Example 1 - Automation Example
  - Example 2 - Illustrating More Options
  - Example 3 - No-Op
  - Example 4 - Usage
- CONFIGURATION FILE
  - File Format
  - Required Entries
  - Optional Entries
- USER REMOVAL
  - User Removal Procedure
- RELATED SOFTWARE
- RETURN STATUS

# NAME

mirror_ldap_groups.pl v2.4.2 - Mirror specified LDAP groups in Perforce.

# SYNOPSIS

mirror_ldap_groups.pl [-c cfg_file] [-g group[,group2,...]] [-o user[,user2,...]] [-i|-b2] [-s ldap_server] [-p ldap_port] [-d|-D] [-n]

OR

mirror_ldap_groups.pl {-h|-man}

# DESCRIPTION

## Overview

This script is as a one-way integration from LDAP to Perforce. It mirrors group membership of a specified list of groups from an LDAP server, such as Active Directory (AD), into Perforce.

For each group processed, a corresponding Perforce group of the same name is created, and updated to contain the same users. If the users in AD do not yet exist in Perforce, Perforce accounts are created using the information available from AD (so long as there are available licenses). Changes to the FullName and Email address fields are detected in LDAP and propagated to Perforce.

If the LDAP group includes other groups, they are mirrored as Perforce subgroups by default. If the LDAP group is empty, a warning message is displayed, and processing continues. Empty LDAP groups are not treated as errors, and do not cause a non-zero return status.

The 'Users' and 'Subgroups' fields of the Perforce group spec are updated based on information from AD. Other fields, such as 'Owners', timeouts and Max* settings, are unaffected.

## Usage Notes

The list of AD groups to process can be specified in the config file or the command line.

Upon completion, a summary of errors and updates is displayed.

This script is intended to be called routinely (e.g every 10 minutes by a cron job or other scheduler).

# ARGUMENTS

## -c[fg] cfg_file

Specify the config file to use. The default is mirror_ldap_groups.cfg in the current directory.

## -g[roups] group[,group2,...]

Specify a comma-delimited list of LDAP groups to mirror in Perforce. Subordinate groups are implied and need not be listed explicitly.

## -o[wners] user[,user2,...]

Specify a comma-delimited list of users to replace the 'Owners' field of the specified group(s).

## -i[gnore]

If the -i flag is specified, any groups defined in LDAP that are members of the specified groups are ignored, rather than mirrored as Subgroups in Perforce. The 'Subgroups' field the group spec is unaffected with '-i'.

The '-i' flag is incompatible with '-b2'.

## -b2

Specify '-b2' to enable a custom behavior for handling Subgroups in Perforce. When '-b2' is specified, any groups defined defined in LDAP that are members of the specified groups are ignored (similar to '-i'). Instead, the membership of any existing Subgroups defined in the group spec in Perforce is queried, and compared against the membership if the parent group. Perforce Subgroups may contain only a subset of the users defined in the specified group (the parent group) when '-b2' is specified. Any users detected in subgroups of the specified group are removed from the group. Other than removal from the group, those accounts are not otherwise affected.

The '-b2' flag is incompatible with '-i'.

## -s[erver] ldap_server

Specify the LDAP server (DNS name or IP address). A default value can be configured by adding an LDAP_HOST value in the configuration file.

## -p[ort] ldap_port

Specify the LDAP server port. A default value can be configured by adding an LDAP_PORT value in the configuration file.

## -d[ebug]

Enable verbose debug mode.

## -D[EBUG]

Same as '-d', but even more pedantic (verbose, noisy).

## -n[oop]

Specify No Op mode, indicating that the script should display what it would do with given arguments and environment, but take no action that affects data. Users that would be added to Perforce are displayed, but those users are not actually added.

## -h[elp]|-man

Display a usage message. The -h display a short synopsis only, while -man displays this manual page.

# EXAMPLES

The `p4master_run` wrapper script is called first, providing the Perforce instance number. This ensures the necessary Perforce environment settings are loaded from `/p4/common/bin/p4_vars`.

These examples use the long options, e.g. '-groups' rather than '-g'; both styles are equivalent.

## Example 1 - Automation Example

A typical usage example, as might be coded in the wrapper script:

`p4master_run 1 mirror_ldap_groups.pl -groups p4.users -server ad.mycompany.com -port 389`

## Example 2 - Illustrating More Options

Example running against Perforce server instance 2, processing multiple groups and a non-default config file containing LDAP server and bind account info:

`p4master_run 2 mirror_ldap_groups.pl -groups p4.dev,p4.qa,p4.automation -cfg mirror_ldap_groups.mycompany.cfg`

## Example 3 - No-Op

A No-Op Usage Example, with maximum verbosity:

`p4master_run 1 mirror_ldap_groups.pl -groups p4.users -server ad.mycompany.com -port 389 -noop -DEBUG`

## Example 4 - Usage

Get usage info on the comand line:

`mirror_ldap_groups.pl -h`

or:

`mirror_ldap_groups.pl -man`

# CONFIGURATION FILE

The config file must define the following values:

## File Format

The config file contains variables names and their, separated by the first space on the line. Any subsequent spaces are interpreted as part of the value. Comment lines start with '#'. Blank lines are ignored, as are leading and trailing whitespace.

## Required Entries

At a minimum, the config file must define these entries:

- LDAP_BIND_USER

  Define a static 'bind' account that has enough access within LDAP query basic user data and read group data.

- LDAP_BIND_PASSWORD

  Define the password for the LDAP_BIND_USER.

- LDAP_READ_DN

  Define the DN string for the bind user. Your resident LDAP guru can help provide this.

- DEFAULT_EMAIL_DOMAIN

  Define a default email domain, just in case the LDAP query for a user's email comes up blank. This is used to guess the user's email domain as userid@default_email_domain.

## Optional Entries

If these optional values are defined, they don't need to be provided on the command line. If the corresponding command line flag is provided, the value in the config file is ignored.

- LDAP_HOST

  Specify the LDAP or Active Directory server (DNS name or IP address). If LDAP_HOST is defined in the config file, the '-s' flag is not required on the command line.

- LDAP_PORT

  Specify the port to connect to LDAP on. This corresponds to the '-p' flag on the command line. If the LDAP_PORT value is defined in the config file, the '-s' flag is not required on the command line.

- LDAP_GROUPS

  The LDAP_GROUPS value may list a single group or a comma-delimted list of groups. If the LDAP_GROUPS value is defined in the config file, the '-g' flag is not required on the command line.

# USER REMOVAL

Users removed from LDAP are not automatically removed from Perforce.

## User Removal Procedure

The following manual procedure illustrates how user accounts that do not exist in any Perforce group can be detected and optionally removed.

Users that do not exist in any group in Perforce can be detected with this command:

`checkusers_not_in_group.py` > `users_not_in_any_group.txt`

`cat users_not_in_any_group.txt`

The users listed in the `users_not_in_any_group.txt` file can be considered candidates for removal.

The recommended procedure for removing a user is to use the P4Admin user interface to manually remove user accounts, following whatever policy and procedures are identified for removing users in your organization. Using P4Admin makes it easy to evaluate the impact of removing an account, indicating (for example) which workspaces will be removed. Workspace remove can be problematic if the user to be removed created (and thus is listed as the owner of) workspaces actively used by other users or official builds.

The script `p4deleteuser.py` is a forceful and potentially dangerous user removal script, as it will remove all workspaces for which the user is indicated as the owner, and cancel any checked out files. If you decide that script is appropriate, you can hand-edit and trim the list of users in `users_not_in_any_group.txt` to create a new file, `users_to_remove.txt`. Then remove those user accounts with this command:

`p4deleteuser.py users_to_remove.txt`

The `checkusers_not_in_group.py` and `p4deleteuser.py` scripts can be found in the Maintenance folder of the Server Delpoyment Package (SDP).

# RELATED SOFTWARE

This depends on several Perl Modules. Key modules are:

- OS.pm - Abstraction layer for platform (e.g. Mac/Linux/Windows) variations.

- Cmd.pm - Shell command line wrapper.

- Misc.pm - Misc Perl utils.

- Msg.pm - Message interface to encourage consistent look and feel, and simplify logging.

# RETURN STATUS

Zero indicates normal completion, Non-Zero indicates an error. In event of a non-zero exit code, all output (stdout and stderr) should be scanned to determine the cause. Generally a clean indication will be given upon failure.