#!/usr/bin/perl
#
# This is a sample implementation of a UID/GID GPFS remapping helper 
# application pair, provided for testing and illustrative purposes.  It uses 
# the Full Name (a.k.a. gecos) field in /etc/passwd as the globally unique user
# name.  No name-based GID remapping is done in this implementation.  When 
# remapping for the purposes of credentials checking (intent is 'credentials'),
# we do remapping for the UID based on the symbolic name, and replace the 
# entire list of GIDs with the GIDs of the user on the home cluster.
#

$debug = 0;

if ($#ARGV != 3)
{
  die("Usage: mmuid2name domain intent nUids nGids\n");
}

$domain = $ARGV[0];
$intent = $ARGV[1];
$nUids = $ARGV[2];
$nGids = $ARGV[3];
print STDERR "$domain $intent $nUids $nGids\n" if $debug;

# Basic argument sanity checking
if ( ($intent ne "credentials") && ($intent ne "stat") && ($intent ne "acl") )
{
  die("Invalid intent value: $intent\n");
}

if ($nUids == 0 && ($intent eq "credentials"))
{
  die("The number of UIDs to be remapped cannot be zero\n");
}
 
# Read the list of UIDs and GIDs
for ($i = 0; $i < $nUids; $i++)
{
  $uid[$i] = <STDIN>;
  chop($uid[$i]);
  print(STDERR "uid: $uid[$i]\n") if $debug;
}
for ($i = 0; $i < $nGids; $i++)
{
  $gid[$i] = <STDIN>;
  chop($gid[$i]);
  print (STDERR "gid: $gid[$i]\n") if $debug;
}

# Go through the list of uids, and for those that are known, output the
# full name (aka gecos field).  For those uids that are not found, output
# "UNKNOWN USER" string.  The choice of string to denote an unknown user is
# arbitrary, anything will do as long as both mmuid2name and mmname2uid use
# the same convention.  An empty string would a logical choice for a real-life
# situation, since it minimizes the size of the messages passed between nodes
# for UID remapping purposes.  However, in this example a more definitive 
# string would work better since /etc/passwd often has empty gecos fields.
for ($i = 0; $i < $nUids; $i++)
{
  @f = getpwuid($uid[$i]);
  if ($#f != -1) 
  {
    print (STDERR "$f[6]\n") if $debug;
    print ("$f[6]\n");
  }
  else
  {
    print (STDERR "UNKNOWN USER\n") if $debug;
    print ("UNKNOWN USER\n");
  }
}

# In this implementation, for the purposes of credentials checking we only remap
# uids but not gids.  We don't need to output anything at all for gids, so
# we quit here.

if ($intent eq "credentials")
{
  exit(0);
}

# Since we don't try to do remapping for gids for stat, there's no additional 
# work. However, we still need to output something (an empty line in our case)
# because the convention is to generate the stated number of output lines for
# intents other than 'credentials'
for ($i = 0; $i < $nGids; $i++)
{
  print "\n";
}
