/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
-/*
+/*
* (5) Add functions to process supergroups:
* ChangeIDEntry(), RemoveFromSGEntry(),
* AddToSGEntry(), GetListSG2().
#include <afsconfig.h>
#include <afs/param.h>
+#include <afs/stds.h>
+#include <roken.h>
-#include <afs/stds.h>
-#include <sys/types.h>
-#include <stdio.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-#include <string.h>
#include <lock.h>
#include <ubik.h>
#include <rx/xdr.h>
#include <afs/com_err.h>
#include <afs/cellconfig.h>
+
#include "ptserver.h"
#include "pterror.h"
#include "ptprototypes.h"
-#include <stdlib.h>
/* Foreign cells are represented by the group system:authuser@cell*/
#define AUTHUSER_GROUP "system:authuser"
* just after ubik_ServerInit.
*/
-void
+void
pt_hook_write(void)
{
extern struct ubik_dbase *ubik_dbase;
#endif /* SUPERGROUPS */
/* CorrectUserName - Check to make sure a user name is OK. It must not include
- * either a colon (or it would look like a group) or an atsign (or it would
- * look like a foreign user). The length is checked as well to make sure
- * that the user name, an atsign, and the local cell name will fit in
- * PR_MAXNAMELEN. This is so this user can fit in another cells database as
- * a foreign user with our cell name tacked on. This is a predicate, so it
- * return one if name is OK and zero if name is bogus. */
+ * either a colon (or it would look like a group) or a newline (which can
+ * confuse some ptdb code, depending on the format we're reading from).
+ * This is a predicate, so it return one if name is OK and zero if name is
+ * bogus. */
static int
CorrectUserName(char *name)
{
- extern int pr_realmNameLen;
-
/* We accept foreign names, so we will deal with '@' later */
if (strchr(name, ':') || strchr(name, '\n'))
return 0;
- if (strlen(name) >= PR_MAXNAMELEN - pr_realmNameLen - 1)
+ if (strlen(name) >= PR_MAXNAMELEN)
return 0;
return 1;
}
CorrectGroupName(struct ubik_trans *ut, char aname[PR_MAXNAMELEN], /* name for group */
afs_int32 cid, /* caller id */
afs_int32 oid, /* owner of group */
+ afs_int32 admin, /* non-zero if admin */
char cname[PR_MAXNAMELEN]) /* correct name for group */
{
afs_int32 code;
- int admin;
char *prefix; /* ptr to group owner part */
char *suffix; /* ptr to group name part */
char name[PR_MAXNAMELEN]; /* correct name for group */
if (strlen(aname) >= PR_MAXNAMELEN)
return PRBADNAM;
- admin = pr_noAuth || IsAMemberOf(ut, cid, SYSADMINID);
-
- if (oid == 0)
- oid = cid;
/* Determine the correct prefix for the name. */
if (oid == SYSADMINID)
strcpy(name, aname); /* in case aname & cname are same */
suffix = strchr(name, ':');
+ /* let e.g. pt_util create groups with "wrong" names (like
+ * an orphan whose parent ID was reused). Check that they look like
+ * groups (with a colon) or otherwise are good user names. */
+ if (pr_noAuth) {
+ strcpy(cname, aname);
+ goto done;
+ }
if (suffix == 0) {
/* sysadmin can make groups w/o ':', but they must still look like
* legal user names. */
return 1;
if (cid == SYSADMINID)
return 1; /* special case fileserver */
- if (restricted && ((mem == PRP_ADD_MEM) || (mem == PRP_REMOVE_MEM)) && (any == 0))
- return 0;
+ if (restricted) {
+ if (mem == PRP_ADD_MEM || mem == PRP_REMOVE_MEM) {
+ /* operation is for adding/removing members from a group */
+ return 0;
+ }
+ if (mem == 0 && any == 0) {
+ /* operation is for modifying an entry (or some administrative
+ * global operations) */
+ return 0;
+ }
+ }
if (tentry) {
flags = tentry->flags;
oid = tentry->owner;
/* get and init a new entry */
afs_int32 code;
afs_int32 newEntry;
+ afs_int32 admin;
struct prentry tentry, tent;
char *atsign;
memset(&tentry, 0, sizeof(tentry));
- if ((oid == 0) || (oid == ANONYMOUSID))
+ admin = pr_noAuth || IsAMemberOf(at, creator, SYSADMINID);
+
+ if (oid == 0 || oid == ANONYMOUSID) {
+ if (!admin && creator == 0)
+ return PRBADARG;
oid = creator;
+ }
if (flag & PRGRP) {
- code = CorrectGroupName(at, aname, creator, oid, tentry.name);
+ code = CorrectGroupName(at, aname, creator, oid, admin, tentry.name);
if (code)
return code;
if (strcmp(aname, tentry.name) != 0)
newEntry = AllocBlock(at);
if (!newEntry)
return PRDBFAIL;
-#ifdef PR_REMEMBER_TIMES
tentry.createTime = time(0);
-#endif
if (flag & PRGRP) {
tentry.flags = PRGRP;
}
} else {
/* A foreign user: <name>@<cell>. The foreign user is added to
- * its representing group. It is
+ * its representing group. It is
*/
char *cellGroup;
afs_int32 pos, n;
/* To create the user <name>@<cell> the group AUTHUSER_GROUP@<cell>
* must exist.
*/
- cellGroup =
- (char *)malloc(strlen(AUTHUSER_GROUP) + strlen(atsign) + 1);
- strcpy(cellGroup, AUTHUSER_GROUP);
- strcat(cellGroup, atsign);
+ if (asprintf(&cellGroup, "%s%s", AUTHUSER_GROUP, atsign) < 0)
+ return PRNOMEM;
pos = FindByName(at, cellGroup, ¢ry);
free(cellGroup);
if (!pos)
return PRBADARG;
tentry.id = *aid;
} else {
- /* Allocate an ID special for this foreign user. It is based
+ /* Allocate an ID special for this foreign user. It is based
* on the representing group's id and nusers count.
*/
tentry.id = allocNextId(at, ¢ry);
/* write updated entry for group */
code = pr_Write(at, 0, pos, ¢ry, sizeof(centry));
+ if (code)
+ return PRDBFAIL;
/* Now add the new user entry to the database */
- tentry.creator = creator;
+ if (creator == 0)
+ tentry.creator = tentry.id;
+ else
+ tentry.creator = creator;
*aid = tentry.id;
code = pr_WriteEntry(at, 0, newEntry, &tentry);
if (code)
}
/* Admins don't get charged for creating a group.
- * If in noAuth mode, you get changed for it but you
+ * If in noAuth mode, you get changed for it but you
* are still allowed to create as many groups as you want.
*/
admin = ((creator == SYSADMINID)
tentry.ngroups = tentry.nusers = 20;
}
- tentry.creator = creator;
+ if (creator == 0)
+ tentry.creator = tentry.id;
+ else
+ tentry.creator = creator;
*aid = tentry.id;
code = pr_WriteEntry(at, 0, newEntry, &tentry);
if (code)
code = pr_ReadEntry(at, 0, temp, &tentry);
if (code != 0)
return code;
-#ifdef PR_REMEMBER_TIMES
tentry.removeTime = time(0);
-#endif
for (i = 0; i < PRSIZE; i++) {
if (tentry.entries[i] == aid) {
tentry.entries[i] = PRBADID;
* entry if appropriate */
afs_int32
-ChangeIDEntry(register struct ubik_trans *at, register afs_int32 aid, afs_int32 newid, register afs_int32 bid)
+ChangeIDEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 newid, afs_int32 bid)
{
- register afs_int32 code;
+ afs_int32 code;
struct prentry tentry;
struct contentry centry;
afs_int32 temp;
* continuation entry if appropriate */
afs_int32
-RemoveFromSGEntry(register struct ubik_trans *at, register afs_int32 aid, register afs_int32 bid)
+RemoveFromSGEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 bid)
{
- register afs_int32 code;
+ afs_int32 code;
struct prentry tentry;
struct prentryg *tentryg;
struct contentry centry;
code = pr_ReadEntry(at, 0, temp, &tentry);
if (code != 0)
return code;
-#ifdef PR_REMEMBER_TIMES
tentry.removeTime = time(NULL);
-#endif
tentryg = (struct prentryg *)&tentry;
for (i = 0; i < SGSIZE; i++) {
if (tentryg->supergroup[i] == aid) {
} /* for all coentry slots */
hloc = nptr;
nptr = centry.next;
- memcpy((char *)¢ry, (char *)&hentry, sizeof(centry));
+ memcpy(&hentry, ¢ry, sizeof(centry));
} /* while there are coentries */
return PRNOENT;
}
if (entry->id == aid)
return PRINCONSISTENT;
-#ifdef PR_REMEMBER_TIMES
entry->addTime = time(0);
-#endif
for (i = 0; i < PRSIZE; i++) {
if (entry->entries[i] == aid)
return PRIDEXIST;
afs_int32
AddToSGEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_int32 aid)
{
- register afs_int32 code;
+ afs_int32 code;
afs_int32 i;
struct contentry nentry;
struct contentry aentry;
if (entry->id == aid)
return PRINCONSISTENT;
-#ifdef PR_REMEMBER_TIMES
entry->addTime = time(NULL);
-#endif
entryg = (struct prentryg *)entry;
for (i = 0; i < SGSIZE; i++) {
if (entryg->supergroup[i] == aid)
afs_int32
AddToPRList(prlist *alist, int *sizeP, afs_int32 id)
{
- char *tmp;
+ afs_int32 *tmp;
int count;
if (alist->prlist_len >= *sizeP) {
count = alist->prlist_len + 100;
if (alist->prlist_val) {
- tmp =
- (char *)realloc(alist->prlist_val, count * sizeof(afs_int32));
+ tmp = realloc(alist->prlist_val, count * sizeof(afs_int32));
} else {
- tmp = (char *)malloc(count * sizeof(afs_int32));
+ tmp = malloc(count * sizeof(afs_int32));
}
if (!tmp)
return (PRNOMEM);
- alist->prlist_val = (afs_int32 *) tmp;
+ alist->prlist_val = tmp;
*sizeP = count;
}
alist->prlist_val[alist->prlist_len++] = id;
afs_int32
GetListSG2(struct ubik_trans *at, afs_int32 gid, prlist *alist, afs_int32 *sizeP, afs_int32 depth)
{
- register afs_int32 code;
+ afs_int32 code;
struct prentry tentry;
struct prentryg *tentryg = (struct prentryg *)&tentry;
afs_int32 i;
afs_int32
GetSGList(struct ubik_trans *at, struct prentry *tentry, prlist *alist)
{
- register afs_int32 code;
+ afs_int32 code;
afs_int32 i;
struct contentry centry;
struct prentryg *tentryg;
}
if (build) {
- /* Only rebuild database if the db was deleted (the header is zero) and we
- * are running noAuth. */
+ /* Only rebuild database if the db was deleted (the header is zero) */
char *bp = (char *)&cheader;
int i;
for (i = 0; i < sizeof(cheader); i++) {
break;
}
}
- if (!pr_noAuth) {
- code = PRDBBAD;
- afs_com_err(whoami, code,
- "Can't rebuild database because not running NoAuth");
- }
}
if (code) {
struct prentry tentry, tent;
afs_int32 loc;
afs_int32 oldowner;
+ afs_int32 admin;
char holder[PR_MAXNAMELEN];
char temp[PR_MAXNAMELEN];
char oldname[PR_MAXNAMELEN];
code = pr_ReadEntry(at, 0, loc, &tentry);
if (code)
return PRDBFAIL;
- if (restricted && !IsAMemberOf(at, cid, SYSADMINID))
+ if (restricted && !IsAMemberOf(at, cid, SYSADMINID))
return PRPERM;
if (tentry.owner != cid && !IsAMemberOf(at, cid, SYSADMINID)
&& !IsAMemberOf(at, cid, tentry.owner) && !pr_noAuth)
return PRPERM;
-#ifdef PR_REMEMBER_TIMES
tentry.changeTime = time(0);
-#endif
+ admin = pr_noAuth || IsAMemberOf(at, cid, SYSADMINID);
/* we're actually trying to change the id */
if (newid && (newid != aid)) {
- if (!IsAMemberOf(at, cid, SYSADMINID) && !pr_noAuth)
+ if (!admin)
return PRPERM;
pos = FindByID(at, newid);
return code;
}
/* Look through cont entries too. This needs to be broken into
- * seperate transaction so that no one transaction becomes too
+ * seperate transaction so that no one transaction becomes too
* large to complete.
*/
for (nptr = tentry.next; nptr; nptr = centry.next) {
/* don't let foreign cell groups change name */
if (atsign != NULL)
return PRPERM;
- code = CorrectGroupName(at, name, cid, tentry.owner, tentry.name);
+
+ if (tentry.owner == 0 || tentry.owner == ANONYMOUSID)
+ tentry.owner = cid;
+
+ code = CorrectGroupName(at, name, cid, tentry.owner, admin, tentry.name);
if (code)
return code;
}
cellEntry->nusers = htonl(id);
- /* use the field nusers to keep
+ /* use the field nusers to keep
* the next available id in that
* foreign cell's group. Note :
* It would seem more appropriate
* to use ngroup for that and nusers
* to enforce the quota, however pts
- * does not have an option to change
+ * does not have an option to change
* foreign users quota yet */
id = (id << 16) | cellid;
/*
* The only thing that we want to make sure here is that
* the id is in the legal range of this group. If it is
- * a duplicate we don't care since it will get caught
+ * a duplicate we don't care since it will get caught
* in a different check.
*/
if (cellid != groupid)
return 0; /* not in range */
- /*
+ /*
* if we got here we're ok but we need to update the nusers
- * field in order to get the id correct the next time that
+ * field in order to get the id correct the next time that
* we try to allocate it automatically
*/