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