[OpenAFS-devel] New subcommand for pts

Sven Oehme oehmes@de.ibm.com
Mon, 14 Feb 2005 20:02:27 +0100


This is a multipart message in MIME format.
--=_alternative 0068963BC1256FA8_=
Content-Type: text/plain; charset="US-ASCII"

Hello,

we have introduced a new subcommand for pts  ..

it adds and removes a user to or from a list of given groups with one 
command.
if the user doesn't exist, he creates the user and adds him into the 
necessary groups .

see some examples :

localhost# pts help setgroups

pts setgroups: Set a user into a fixed list of groups

Usage: pts setgroups -user <user name>+ -group <group name>+ [-cell
<cell name>] [-noauth] [-force] [-help]
Where: -noauth  run unauthenticated
       -force   Continue oper despite reasonable errors

---------------
localhost:~ # pts listentries -users
Name                          ID  Owner Creator
anonymous                  32766   -204    -204
admin                          1   -204   32766
sef                            2   -204       1
sef2                           3   -204       1
sef3                           4   -204       1
localhost:~ # pts listentries -groups
Name                          ID  Owner Creator
system:administrators       -204   -204    -204
system:backup               -205   -204    -204
system:anyuser              -101   -204    -204
system:authuser             -102   -204    -204
system:ptsviewers           -203   -204    -204
developer                   -206      1       1
tester                      -207      1       1
designer                    -208      1       1
c                           -209   -204       1
d                           -210   -204       1
e                           -211      1       1
localhost:~ # pts membership sef2
Groups sef2 (id: 3) is a member of:
  d
  c
  designer
  tester
  developer

localhost:~ # pts setgroups -user sef2 -group d c a
Adding sef2 to a
Creating group a
group a has id -212
Removing sef2 from designer
Removing sef2 from developer
Removing sef2 from tester
localhost:~ # pts membership sef2
Groups sef2 (id: 3) is a member of:
  a
  d
  c

localhost:~ # pts setgroups -user sef4 -group d c a h
Could not find user sef4 -- creating
User sef4 has id 6
Adding sef4 to a
Adding sef4 to c
Adding sef4 to d
Adding sef4 to h
Creating group h
group h has id -213
localhost:~ # pts membership sef4
Groups sef4 (id: 6) is a member of:
  h
  a
  d
  c

localhost:~ # pts listentries -users
Name                          ID  Owner Creator
anonymous                  32766   -204    -204
admin                          1   -204   32766
sef                            2   -204       1
sef2                           3   -204       1
sef3                           4   -204       1
sef4                           6   -204       1

localhost:~ # pts listentries -groups
Name                          ID  Owner Creator
system:administrators       -204   -204    -204
system:backup               -205   -204    -204
system:anyuser              -101   -204    -204
system:authuser             -102   -204    -204
system:ptsviewers           -203   -204    -204
developer                   -206      1       1
tester                      -207      1       1
designer                    -208      1       1
c                           -209   -204       1
d                           -210   -204       1
e                           -211      1       1
a                           -212   -204       1
h                           -213   -204       1


CAVEAT:
with pts setgroups all ids are always dynamic assigned, there is no (not
yet) support for given id, like pts createuser
or pts creategroup

here is the code :


--- openafs-cvs/src/ptserver/pts.c      2005-02-14 13:25:33.349705968 
+0100
+++ openafs-cvs/src/ptserver/pts.c.new  2005-02-14 13:27:53.818351488 
+0100
@@ -578,6 +578,188 @@
     return 0;
 }
 
+static int compare_nameentry(const void *x, const void *y)
+{
+       return strcasecmp(x, y);
+}
+
+int SetGroups(as)
+register struct cmd_syndesc *as;
+{
+    register afs_int32 code;
+    idlist ids;
+
+    prname name_vals[1];
+    namelist names;
+    int i;
+    namelist found;
+    int j;
+    afs_int32 id;
+    char *name;
+
+    prname wanted_vals[PR_MAXGROUPS];
+    namelist wanted;
+    struct cmd_item *item;
+
+    int attempts, modified;
+
+    if (as->parms[0].items == NULL) {
+            com_err (whoami, PRBADARG, "; specify at least one user");
+           return PRBADARG;
+    }
+    if (as->parms[0].items->next != NULL) {
+            com_err (whoami, PRBADARG, "; specify at most one user");
+           return PRBADARG;
+    }
+
+    wanted.namelist_len = 0;
+    wanted.namelist_val = wanted_vals;
+
+    i=0;
+
+    for (item = as->parms[1].items; item; item = item->next) {
+           if (strlen(item->data) == 0)
+                   continue;
+           memset(wanted.namelist_val[i], 0, sizeof(prname));
+           strncpy(wanted.namelist_val[i], item->data, sizeof(prname)-1);
+           wanted.namelist_len += 1;
+           i+=1;
+           if (i>=PR_MAXGROUPS) {
+                    com_err (whoami, PRBADARG, "; too many groups");
+                   return PRBADARG;
+           }
+    }
+
+    qsort(wanted.namelist_val, wanted.namelist_len, sizeof(prname),
+         compare_nameentry);
+
+    names.namelist_len = 1;
+    names.namelist_val = name_vals;
+
+    memset(names.namelist_val[0], 0, sizeof(prname));
+    strncpy(names.namelist_val[0], as->parms[0].items->data, 
sizeof(prname)-1);
+
+    attempts = 0;
+
+ again:
+
+    modified = 0;
+
+    if ((pr_NameToId(&names, &ids) != 0) ||
+       (ids.idlist_len != 1) ||
+       (ids.idlist_val[0] == ANONYMOUSID)) {
+           modified = 1;
+           printf("Could not find user %s -- creating\n",
+                  names.namelist_val[0]);
+           id = 0;
+           if (pr_CreateUser(names.namelist_val[0], &id) != 0) {
+                    com_err (whoami, PRBADARG, "; could not create 
user\n");
+                   return PRBADARG;
+           }
+           printf ("User %s has id %d\n", names.namelist_val[0], id);
+           if ((pr_NameToId(&names, &ids) != 0) ||
+               (ids.idlist_len != 1) ||
+               (ids.idlist_val[0] == ANONYMOUSID)) {
+                    com_err (whoami, PRBADARG, 
+                             "; could not find just created user\n");
+                   return PRBADARG;
+           }
+    }
+
+    id = ids.idlist_val[0];
+    name = names.namelist_val[0];
+
+    if (id == ANONYMOUSID) {
+            com_err (whoami, PRBADARG, 
+                     "; got bad entry for %s (id: %d)", name, id);
+           return PRBADARG;
+    }
+
+    found.namelist_val = 0;
+    found.namelist_len = 0;
+    code = pr_IDListMembers(id, &found);
+
+    if (code) {
+            com_err (whoami, PRNOENT, 
+                     "; unable to get membership of %s (id: %d)", name, 
id);
+           return PRNOENT;
+    }
+
+    qsort(found.namelist_val, found.namelist_len, sizeof(prname),
+         compare_nameentry);
+
+    i=0; j=0;
+
+    while ((i<wanted.namelist_len) || (j<found.namelist_len)) {
+           char *want = NULL;
+           char *exist = NULL;
+           char *add = NULL;
+
+
+           if ( (j == found.namelist_len) ||
+                ((i < wanted.namelist_len) &&
+                 (strcasecmp(wanted.namelist_val[i],
+                             found.namelist_val[j]) < 0)) ) {
+
+                   modified = 1;
+                   printf("Adding %s to %s\n", name, 
wanted.namelist_val[i]);
+                   code = pr_AddToGroup(name, wanted.namelist_val[i]);
+
+                   if (code == PRNOENT) {
+                           /* Trying to create group */
+                           id = 0;
+                           printf("Creating group %s\n",
+                                  wanted.namelist_val[i]);
+
+                           /* Explicitly ignore any error here, someone 
else
+                              might also be doing it */
+                           pr_CreateGroup(wanted.namelist_val[i],
+                                          "system:administrators", &id);
+                           printf ("group %s has id %d\n", 
+                                    wanted.namelist_val[i], id);
+                           pr_AddToGroup(name, wanted.namelist_val[i]);
+                   }
+                   i+=1;
+                   continue;
+           }
+
+           if ( (i == wanted.namelist_len) ||
+                ((j < found.namelist_len) && 
+                 (strcasecmp(wanted.namelist_val[i],
+                             found.namelist_val[j]) > 0)) ) {
+
+                   modified = 1;
+                   printf("Removing %s from %s\n", name,
+                          found.namelist_val[j]);
+                   /* Ignoring errors due to possible races, see above */
+                   pr_RemoveUserFromGroup(name, found.namelist_val[j]);
+                   j+=1;
+                   continue;
+           }
+
+           i+=1; j+=1;
+    }
+
+#if 0
+    if (found.namelist_val != NULL)
+           free(found.namelist_val);
+
+    if (ids.idlist_val != NULL)
+           free(ids.idlist_val);
+#endif
+
+    if (modified == 0)
+           return PRSUCCESS;
+
+    if (attempts == 0) {
+           attempts = 1;
+           goto again;
+    }
+
+    com_err (whoami, PRPERM, "; error setting groups");
+    return PRPERM;
+}
+
 int
 Delete(register struct cmd_syndesc *as)
 {
@@ -1078,6 +1260,12 @@
     cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
     add_std_args(ts);
 
+    ts = cmd_CreateSyntax("setgroups",SetGroups,0,
+                         "Set a user into a fixed list of groups");
+    cmd_AddParm(ts, "-user",CMD_LIST,0,"user name");
+    cmd_AddParm(ts, "-group",CMD_LIST,0,"group name");
+    add_std_args (ts);
+
     ts = cmd_CreateSyntax("membership", ListMembership, 0,
                          "list membership of a user or group");
     cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or 
id");


Sven
-------------------------------------------------------------------------------------------------------------------------
Dept. A153,  STG/ISC EMEA AIS Strategy and Architecture
Development Leader Stonehenge 
IBM intranet ---> http://w3.ais.mainz.de.ibm.com/stonehenge/
internet ---> http://www-5.ibm.com/services/de/storage/stonehenge.html
Phone (+49)-6131-84-3151
Fax      (+49)-6131-84-6708
Mobil   (+49)-171-970-6664
E-Mail : oehmes@de.ibm.com
--=_alternative 0068963BC1256FA8_=
Content-Type: text/html; charset="US-ASCII"


<br><font size=2 face="Courier New">Hello,</font>
<br>
<br><font size=2 face="Courier New">we have introduced a new subcommand
for pts &nbsp;..</font>
<br>
<br><font size=2 face="Courier New">it adds and removes a user to or from
a list of given groups with one command.</font>
<br><font size=2 face="Courier New">if the user doesn't exist, he creates
the user and adds him into the necessary groups .</font>
<br>
<br><font size=2 face="Courier New">see some examples :</font>
<br>
<br><font size=2 face="Courier New">localhost# pts help setgroups<br>
</font>
<br><font size=2 face="Courier New">pts setgroups: Set a user into a fixed
list of groups<br>
</font>
<br><font size=2 face="Courier New">Usage: pts setgroups -user &lt;user
name&gt;+ -group &lt;group name&gt;+ [-cell<br>
&lt;cell name&gt;] [-noauth] [-force] [-help]<br>
Where: -noauth &nbsp;run unauthenticated<br>
 &nbsp; &nbsp; &nbsp; -force &nbsp; Continue oper despite reasonable errors<br>
<br>
---------------<br>
localhost:~ # pts listentries -users<br>
Name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;ID &nbsp;Owner Creator<br>
anonymous &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;32766
&nbsp; -204 &nbsp; &nbsp;-204<br>
admin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;1 &nbsp; -204 &nbsp; 32766<br>
sef &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
sef2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; 3 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
sef3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; 4 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
localhost:~ # pts listentries -groups<br>
Name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;ID &nbsp;Owner Creator<br>
system:administrators &nbsp; &nbsp; &nbsp; -204 &nbsp; -204 &nbsp; &nbsp;-204<br>
system:backup &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -205 &nbsp;
-204 &nbsp; &nbsp;-204<br>
system:anyuser &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-101 &nbsp;
-204 &nbsp; &nbsp;-204<br>
system:authuser &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -102 &nbsp; -204
&nbsp; &nbsp;-204<br>
system:ptsviewers &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -203 &nbsp; -204 &nbsp;
&nbsp;-204<br>
developer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
-206 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
tester &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;-207 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
designer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;-208 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
c &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -209 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
d &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -210 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
e &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -211 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
localhost:~ # pts membership sef2<br>
Groups sef2 (id: 3) is a member of:<br>
 &nbsp;d<br>
 &nbsp;c<br>
 &nbsp;designer<br>
 &nbsp;tester<br>
 &nbsp;developer<br>
</font>
<br><font size=2 face="Courier New">localhost:~ # pts setgroups -user sef2
-group d c a<br>
Adding sef2 to a<br>
Creating group a<br>
group a has id -212<br>
Removing sef2 from designer<br>
Removing sef2 from developer<br>
Removing sef2 from tester<br>
localhost:~ # pts membership sef2<br>
Groups sef2 (id: 3) is a member of:<br>
 &nbsp;a<br>
 &nbsp;d<br>
 &nbsp;c<br>
</font>
<br><font size=2 face="Courier New">localhost:~ # pts setgroups -user sef4
-group d c a h<br>
Could not find user sef4 -- creating<br>
User sef4 has id 6<br>
Adding sef4 to a<br>
Adding sef4 to c<br>
Adding sef4 to d<br>
Adding sef4 to h<br>
Creating group h<br>
group h has id -213<br>
localhost:~ # pts membership sef4<br>
Groups sef4 (id: 6) is a member of:<br>
 &nbsp;h<br>
 &nbsp;a<br>
 &nbsp;d<br>
 &nbsp;c<br>
</font>
<br><font size=2 face="Courier New">localhost:~ # pts listentries -users<br>
Name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;ID &nbsp;Owner Creator<br>
anonymous &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;32766
&nbsp; -204 &nbsp; &nbsp;-204<br>
admin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;1 &nbsp; -204 &nbsp; 32766<br>
sef &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
sef2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; 3 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
sef3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; 4 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
sef4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; 6 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
</font>
<br><font size=2 face="Courier New">localhost:~ # pts listentries -groups<br>
Name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;ID &nbsp;Owner Creator<br>
system:administrators &nbsp; &nbsp; &nbsp; -204 &nbsp; -204 &nbsp; &nbsp;-204<br>
system:backup &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -205 &nbsp;
-204 &nbsp; &nbsp;-204<br>
system:anyuser &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-101 &nbsp;
-204 &nbsp; &nbsp;-204<br>
system:authuser &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -102 &nbsp; -204
&nbsp; &nbsp;-204<br>
system:ptsviewers &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -203 &nbsp; -204 &nbsp;
&nbsp;-204<br>
developer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
-206 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
tester &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;-207 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
designer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;-208 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
c &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -209 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
d &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -210 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
e &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -211 &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; 1<br>
a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -212 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; -213 &nbsp; -204 &nbsp; &nbsp; &nbsp; 1<br>
<br>
<br>
CAVEAT:<br>
with pts setgroups all ids are always dynamic assigned, there is no (not<br>
yet) support for given id, like pts createuser<br>
or pts creategroup<br>
</font>
<br><font size=2 face="Courier New">here is the code :</font>
<br>
<br>
<div>
<br><font size=2><tt>--- openafs-cvs/src/ptserver/pts.c &nbsp; &nbsp; &nbsp;
&nbsp;2005-02-14 13:25:33.349705968 +0100<br>
+++ openafs-cvs/src/ptserver/pts.c.new &nbsp; &nbsp; &nbsp; &nbsp;2005-02-14
13:27:53.818351488 +0100<br>
@@ -578,6 +578,188 @@<br>
 &nbsp; &nbsp; return 0;<br>
 }<br>
 <br>
+static int compare_nameentry(const void *x, const void *y)<br>
+{<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;return strcasecmp(x, y);<br>
+}<br>
+<br>
+int SetGroups(as)<br>
+register struct cmd_syndesc *as;<br>
+{<br>
+ &nbsp; &nbsp;register afs_int32 code;<br>
+ &nbsp; &nbsp;idlist ids;<br>
+<br>
+ &nbsp; &nbsp;prname name_vals[1];<br>
+ &nbsp; &nbsp;namelist names;<br>
+ &nbsp; &nbsp;int i;<br>
+ &nbsp; &nbsp;namelist found;<br>
+ &nbsp; &nbsp;int j;<br>
+ &nbsp; &nbsp;afs_int32 id;<br>
+ &nbsp; &nbsp;char *name;<br>
+<br>
+ &nbsp; &nbsp;prname wanted_vals[PR_MAXGROUPS];<br>
+ &nbsp; &nbsp;namelist wanted;<br>
+ &nbsp; &nbsp;struct cmd_item *item;<br>
+<br>
+ &nbsp; &nbsp;int attempts, modified;<br>
+<br>
+ &nbsp; &nbsp;if (as-&gt;parms[0].items == NULL) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;com_err (whoami, PRBADARG, &quot;;
specify at least one user&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return PRBADARG;<br>
+ &nbsp; &nbsp;}<br>
+ &nbsp; &nbsp;if (as-&gt;parms[0].items-&gt;next != NULL) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;com_err (whoami, PRBADARG, &quot;;
specify at most one user&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return PRBADARG;<br>
+ &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp;wanted.namelist_len = 0;<br>
+ &nbsp; &nbsp;wanted.namelist_val = wanted_vals;<br>
+<br>
+ &nbsp; &nbsp;i=0;<br>
+<br>
+ &nbsp; &nbsp;for (item = as-&gt;parms[1].items; item; item = item-&gt;next)
{</tt></font>
<br><font size=2><tt>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if
(strlen(item-&gt;data) == 0)<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;continue;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;memset(wanted.namelist_val[i],
0, sizeof(prname));<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strncpy(wanted.namelist_val[i],
item-&gt;data, sizeof(prname)-1);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;wanted.namelist_len
+= 1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i+=1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (i&gt;=PR_MAXGROUPS)
{<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;com_err
(whoami, PRBADARG, &quot;; too many groups&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;return PRBADARG;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
+ &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp;qsort(wanted.namelist_val, wanted.namelist_len, sizeof(prname),<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;compare_nameentry);<br>
+<br>
+ &nbsp; &nbsp;names.namelist_len = 1;<br>
+ &nbsp; &nbsp;names.namelist_val = name_vals;<br>
+<br>
+ &nbsp; &nbsp;memset(names.namelist_val[0], 0, sizeof(prname));<br>
+ &nbsp; &nbsp;strncpy(names.namelist_val[0], as-&gt;parms[0].items-&gt;data,
sizeof(prname)-1);<br>
+<br>
+ &nbsp; &nbsp;attempts = 0;<br>
+<br>
+ again:<br>
+<br>
+ &nbsp; &nbsp;modified = 0;<br>
+<br>
+ &nbsp; &nbsp;if ((pr_NameToId(&amp;names, &amp;ids) != 0) ||<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;(ids.idlist_len != 1) ||<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;(ids.idlist_val[0] == ANONYMOUSID))
{<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;modified = 1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;Could not
find user %s -- creating\n&quot;,<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; names.namelist_val[0]);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id = 0;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (pr_CreateUser(names.namelist_val[0],
&amp;id) != 0) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;com_err
(whoami, PRBADARG, &quot;; could not create user\n&quot;);</tt></font>
<br><font size=2><tt>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;return PRBADARG;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf (&quot;User %s
has id %d\n&quot;, names.namelist_val[0], id);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((pr_NameToId(&amp;names,
&amp;ids) != 0) ||<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(ids.idlist_len
!= 1) ||<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(ids.idlist_val[0]
== ANONYMOUSID)) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;com_err
(whoami, PRBADARG, <br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &quot;; could not find just created user\n&quot;);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;return PRBADARG;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
+ &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp;id = ids.idlist_val[0];<br>
+ &nbsp; &nbsp;name = names.namelist_val[0];<br>
+<br>
+ &nbsp; &nbsp;if (id == ANONYMOUSID) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;com_err (whoami, PRBADARG, <br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&quot;; got bad entry for %s (id: %d)&quot;, name, id);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return PRBADARG;<br>
+ &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp;found.namelist_val = 0;<br>
+ &nbsp; &nbsp;found.namelist_len = 0;<br>
+ &nbsp; &nbsp;code = pr_IDListMembers(id, &amp;found);<br>
+<br>
+ &nbsp; &nbsp;if (code) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;com_err (whoami, PRNOENT, <br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&quot;; unable to get membership of %s (id: %d)&quot;, name, id);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return PRNOENT;<br>
+ &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp;qsort(found.namelist_val, found.namelist_len, sizeof(prname),<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;compare_nameentry);<br>
+<br>
+ &nbsp; &nbsp;i=0; j=0;<br>
+<br>
+ &nbsp; &nbsp;while ((i&lt;wanted.namelist_len) || (j&lt;found.namelist_len))
{</tt></font>
<br><font size=2><tt>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char
*want = NULL;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char *exist = NULL;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char *add = NULL;<br>
+<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ( (j == found.namelist_len)
||<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
((i &lt; wanted.namelist_len) &amp;&amp;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;(strcasecmp(wanted.namelist_val[i],<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;found.namelist_val[j])
&lt; 0)) ) {<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;modified = 1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;printf(&quot;Adding %s to %s\n&quot;, name, wanted.namelist_val[i]);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;code = pr_AddToGroup(name, wanted.namelist_val[i]);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;if (code == PRNOENT) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* Trying to create group
*/<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id = 0;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;Creating
group %s\n&quot;,<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; wanted.namelist_val[i]);<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* Explicitly ignore any
error here, someone else<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; might also be
doing it */<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pr_CreateGroup(wanted.namelist_val[i],<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;system:administrators&quot;,
&amp;id);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf (&quot;group %s has id %d\n&quot;,
<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;wanted.namelist_val[i],
id);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pr_AddToGroup(name, wanted.namelist_val[i]);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;}<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;i+=1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;continue;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ( (i == wanted.namelist_len)
||<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
((j &lt; found.namelist_len) &amp;&amp; <br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;(strcasecmp(wanted.namelist_val[i],</tt></font>
<br><font size=2><tt>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;found.namelist_val[j]) &gt; 0)) ) {<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;modified = 1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;printf(&quot;Removing %s from %s\n&quot;, name,<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; found.namelist_val[j]);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;/* Ignoring errors due to possible races, see above */<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;pr_RemoveUserFromGroup(name, found.namelist_val[j]);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;j+=1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;continue;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i+=1; j+=1;<br>
+ &nbsp; &nbsp;}<br>
+<br>
+#if 0<br>
+ &nbsp; &nbsp;if (found.namelist_val != NULL)<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;free(found.namelist_val);<br>
+<br>
+ &nbsp; &nbsp;if (ids.idlist_val != NULL)<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;free(ids.idlist_val);<br>
+#endif<br>
+<br>
+ &nbsp; &nbsp;if (modified == 0)<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return PRSUCCESS;<br>
+<br>
+ &nbsp; &nbsp;if (attempts == 0) {<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;attempts = 1;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto again;<br>
+ &nbsp; &nbsp;}<br>
+<br>
+ &nbsp; &nbsp;com_err (whoami, PRPERM, &quot;; error setting groups&quot;);<br>
+ &nbsp; &nbsp;return PRPERM;<br>
+}<br>
+<br>
 int<br>
 Delete(register struct cmd_syndesc *as)<br>
 {<br>
@@ -1078,6 +1260,12 @@<br>
 &nbsp; &nbsp; cmd_AddParm(ts, &quot;-group&quot;, CMD_LIST, 0, &quot;group
name&quot;);<br>
 &nbsp; &nbsp; add_std_args(ts);<br>
 <br>
+ &nbsp; &nbsp;ts = cmd_CreateSyntax(&quot;setgroups&quot;,SetGroups,0,<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;Set a user into a fixed
list of groups&quot;);<br>
+ &nbsp; &nbsp;cmd_AddParm(ts, &quot;-user&quot;,CMD_LIST,0,&quot;user
name&quot;);<br>
+ &nbsp; &nbsp;cmd_AddParm(ts, &quot;-group&quot;,CMD_LIST,0,&quot;group
name&quot;);</tt></font>
<br><font size=2><tt>+ &nbsp; &nbsp;add_std_args (ts);<br>
+<br>
 &nbsp; &nbsp; ts = cmd_CreateSyntax(&quot;membership&quot;, ListMembership,
0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &quot;list membership of a user or
group&quot;);<br>
 &nbsp; &nbsp; cmd_AddParm(ts, &quot;-nameorid&quot;, CMD_LIST, 0, &quot;user
or group name or id&quot;);</tt></font>
<br><font size=2 face="Courier New"><br>
</font>
<br><font size=2 face="Courier New">Sven<br>
-------------------------------------------------------------------------------------------------------------------------<br>
Dept. A153, &nbsp;STG/ISC EMEA AIS Strategy and Architecture<br>
Development Leader Stonehenge <br>
IBM intranet ---&gt; http://w3.ais.mainz.de.ibm.com/stonehenge/<br>
internet ---&gt; http://www-5.ibm.com/services/de/storage/stonehenge.html<br>
Phone (+49)-6131-84-3151<br>
Fax &nbsp; &nbsp; &nbsp;(+49)-6131-84-6708<br>
Mobil &nbsp; (+49)-171-970-6664<br>
E-Mail : oehmes@de.ibm.com</font></div>
--=_alternative 0068963BC1256FA8_=--