source: gpfs_3.1_ker2.6.20/lpp/mmfs/samples/uidremap/mmname2uid @ 16

Last change on this file since 16 was 16, checked in by rock, 16 years ago
  • Property svn:executable set to *
File size: 4.2 KB
Line 
1#!/usr/bin/perl
2#
3# This is a sample implementation of a UID/GID GPFS remapping helper
4# application pair, provided for testing and illustrative purposes.  It uses
5# the Full Name (a.k.a. gecos) field in /etc/passwd as the globally unique user
6# name.  No name-based GID remapping is done in this implementation.  When
7# remapping for the purposes of credentials checking (intent is 'credentials'),
8# we do remapping for the UID based on the symbolic name, and replace the
9# entire list of GIDs with the GIDs of the user on the home cluster.
10
11$debug = 0;
12
13if ($#ARGV != 3)
14{
15  die("Usage: mmname2uid domain intent nUids nGids\n");
16}
17
18$domain = $ARGV[0];
19$intent = $ARGV[1];
20$nUids = $ARGV[2];
21$nGids = $ARGV[3];
22
23# Do basic argument sanity checking
24if ( ($intent ne "credentials") && ($intent ne "stat") && ($intent ne "acl") )
25{
26  die("Invalid intent value: $intent\n");
27}
28
29if ( ($intent eq "credentials") && ($nUids == 0) )
30{
31  die("The number of UIDs to be remapped cannot be zero\n");
32}
33
34if ( ($intent eq "credentials") && ($nUids != 1) )
35{
36  die("Only one UID is allowed for credentials remapping\n");
37}
38 
39# In this sample implementation, we replace the entire list of GIDs
40# with a new list when remapping for credentials checking.  The matching
41# mmuid2name never outputs any GIDs, so we should not be expecting any
42# (a different implementation may handle this differently)
43if ($intent eq "credentials")
44{
45  $nGids = 0;
46}
47
48# Read the list of UIDs and GIDs.  Note that the interface conventions
49# stipulate that when the intent is 'stat', two lines of input will be
50# provided for each ID: symbolic name and original numeric ID.
51for ($i = 0; $i < $nUids; $i++)
52{
53  $name = <STDIN>;
54  print(STDERR $name) if $debug;
55  chop($name);
56  $gcoss{$name} = $i;
57  $uids[$i] = "UNKNOWN USER";
58  if ($intent eq "stat")
59  {
60    $id = <STDIN>;
61    print(STDERR $id) if $debug;
62    chop($id);
63    $orig_uids[$i] = $id;
64  }
65}
66for ($i = 0; $i < $nGids; $i++)
67{
68  $gname = <STDIN>;
69  print(STDERR $gname) if $debug;
70  chop($gname);
71  $gnames{$gname} = $i;
72  if ($intent eq "stat")
73  {
74    $id = <STDIN>;
75    print(STDERR $id) if $debug;
76    chop($id);
77    $orig_gids[$i] = $id;
78  }
79}
80
81# Go though the list of users, as returned by getpwent (normally it's the
82# list from /etc/passwd or NIS), and find users who have their Full Name
83# matching to one of the input names.
84$nFound = 0;
85while(true)
86{
87  @pwent = getpwent();
88  if ($#pwent == -1){ last; }
89  $username = $pwent[0];
90  $uid = $pwent[2];
91  $gid = $pwent[3];
92  $gcos = $pwent[6];
93  if (exists $gcoss{$gcos})
94  {
95    $uids[$gcoss{$gcos}] = $uid;
96    if ($intent eq "credentials")
97    {
98      $gids[$gcoss{$gcos}] = $gid;
99      $usernames[$gcoss{$gcos}] = $username;
100    }
101    $nFound++;
102    last if $nFound >= $nUids;
103  }
104}
105endpwent();
106
107# Get UID/GID of 'nobody'.  In this implementation, we return those when the
108# symbolic name is not found in our /etc/passwd.
109@a = getpwnam("nobody");
110$nobody_uid = $a[2];
111$nobody_gid = $a[3];
112
113# In this implementation, the convention is to use "UNKNOWN USER" string
114# to denote a name that has not been found.
115for ($i = 0; $i < $nUids; $i++)
116{
117  # if the user is not found, print ids of nobody
118  if ($uids[$i] eq "UNKNOWN USER")
119  {
120    printf("%u\n", $nobody_uid);
121    printf("%u\n", $nobody_gid) if ($intent eq "credentials");
122    next;
123  }
124 
125  printf("%u\n", $uids[$i]);
126  # if we are remapping for credentials checking, get a list of groups
127  # that the user belongs to
128  if ($intent eq "credentials")
129  {
130    # primary gid
131    printf("%u\n", $gids[$i]);
132    # supplementary groups
133    while(true)
134    {
135      ($name, $passwd, $gid, $members) = getgrent();
136      last if $name eq "";
137      # skip group if it's user's primary group
138      next if $gid == $gids[$i];
139      @memberlist = split(' ', $members);
140      foreach(@memberlist)
141      {
142        if ($_ eq $usernames[$i])
143        {
144          printf("%u\n", $gid);
145          last;
146        }
147      }
148    }
149  }
150}
151
152# In this example, we don't do remapping for gids for stat.  We choose not
153# to remap gids at all, i.e. return the same gid that was supplied to us.  An
154# alternative would be to return gid of 'nobody' for all gids, but that is
155# hardly useful.
156for ($i = 0; $i < $nGids; $i++)
157{
158  printf("%u\n", $orig_gids[$i]);
159}
Note: See TracBrowser for help on using the repository browser.