2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
15 #include <afs/afs_consts.h>
28 #include <afs/afs_assert.h>
29 #include <afs/ptserver.h>
30 #include <afs/ptuser.h>
35 static int BadName(char *aname, char *cellname);
38 ZapAcl (struct Acl *acl)
43 ZapList(acl->pluslist);
44 ZapList(acl->minuslist);
49 ZapList (struct AclEntry *alist)
51 struct AclEntry *tp, *np;
52 for (tp = alist; tp; tp = np) {
59 PruneList (struct AclEntry **ae, int dfs)
62 struct AclEntry *te, *ne;
66 for(te = *ae;te;te=ne) {
67 if ((!dfs && te->rights == 0) || te->rights == -1) {
90 FindList (struct AclEntry *alist, char *aname)
93 if (!strcasecmp(alist->name, aname))
101 ChangeList (struct Acl *al, afs_int32 plus, char *aname, afs_int32 arights,
104 struct AclEntry *tlist;
105 tlist = (plus ? al->pluslist : al->minuslist);
106 tlist = FindList (tlist, aname);
108 /* Found the item already in the list. */
109 /* modify rights in case of reladd */
110 /* and reladd only, use standard - */
111 /* add, ie. set - otherwise */
112 if ( artypep == NULL )
113 tlist->rights = arights;
114 else if ( *artypep == reladd )
115 tlist->rights |= arights;
116 else if ( *artypep == reldel )
117 tlist->rights &= ~arights;
119 tlist->rights = arights;
122 al->nplus -= PruneList(&al->pluslist, al->dfs);
124 al->nminus -= PruneList(&al->minuslist, al->dfs);
127 if ( artypep != NULL && *artypep == reldel )
128 /* can't reduce non-existing rights */
131 /* Otherwise we make a new item and plug in the new data. */
132 tlist = (struct AclEntry *) malloc(sizeof (struct AclEntry));
134 if( FAILED(StringCbCopy(tlist->name, sizeof(tlist->name), aname))) {
135 fprintf (stderr, "name - not enough space");
138 tlist->rights = arights;
140 tlist->next = al->pluslist;
141 al->pluslist = tlist;
143 if (arights == 0 || arights == -1)
144 al->nplus -= PruneList(&al->pluslist, al->dfs);
146 tlist->next = al->minuslist;
147 al->minuslist = tlist;
150 al->nminus -= PruneList(&al->minuslist, al->dfs);
156 * Create an empty acl, taking into account whether the acl pointed
157 * to by astr is an AFS or DFS acl. Only parse this minimally, so we
158 * can recover from problems caused by bogus ACL's (in that case, always
159 * assume that the acl is AFS: for DFS, the user can always resort to
160 * acl_edit, but for AFS there may be no other way out).
168 tp = (struct Acl *)malloc(sizeof (struct Acl));
170 tp->nplus = tp->nminus = 0;
171 tp->pluslist = tp->minuslist = 0;
174 if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
179 if (astr == NULL || sscanf_s(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell, sizeof(tp->cell)) <= 0) {
187 /* clean up an access control list of its bad entries; return 1 if we made
188 any changes to the list, and 0 otherwise */
190 CleanAcl(struct Acl *aa, char *cellname)
192 struct AclEntry *te, **le, *ne;
195 /* Don't correct DFS ACL's for now */
199 /* prune out bad entries */
200 changes = 0; /* count deleted entries */
202 for(te = aa->pluslist; te; te=ne) {
204 if (BadName(te->name, cellname)) {
215 for(te = aa->minuslist; te; te=ne) {
217 if (BadName(te->name, cellname)) {
231 ParseAcl (char *astr, int astr_size)
233 int nplus, nminus, i, trights, ret;
235 char tname[ACL_MAXNAME];
236 struct AclEntry *first, *next, *last, *tl;
240 if( FAILED(StringCbLength(astr, astr_size, &len))) {
241 fprintf (stderr, "StringCbLength failure on astr");
244 if (astr == NULL || len == 0)
248 ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
250 ret = sscanf_s(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell, sizeof(ta->cell));
256 astr = SkipLine(astr);
258 ret = sscanf(astr, "%d", &ta->nminus);
260 ret = sscanf_s(astr, "%d", &ta->nminus);
266 astr = SkipLine(astr);
273 for(i=0;i<nplus;i++) {
275 ret = sscanf(astr, "%100s %d", tname, &trights);
277 ret = sscanf_s(astr, "%100s %d", tname, sizeof(tname), &trights);
281 astr = SkipLine(astr);
282 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
287 if( FAILED(StringCbCopy(tl->name, sizeof(tl->name), tname))) {
288 fprintf (stderr, "name - not enough space");
291 tl->rights = trights;
297 ta->pluslist = first;
301 for(i=0;i<nminus;i++) {
303 ret = sscanf(astr, "%100s %d", tname, &trights);
305 ret = sscanf_s(astr, "%100s %d", tname, sizeof(tname), &trights);
309 astr = SkipLine(astr);
310 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
315 if( FAILED(StringCbCopy(tl->name, sizeof(tl->name), tname))) {
316 fprintf (stderr, "name - not enough space");
319 tl->rights = trights;
325 ta->minuslist = first;
330 for (;first; first = next) {
334 first = ta->pluslist;
337 for (;first; first = next) {
346 AclToString(struct Acl *acl)
348 static char mydata[AFS_PIOCTL_MAXSIZE];
349 char tstring[AFS_PIOCTL_MAXSIZE];
354 if( FAILED(StringCbPrintf(dfsstring, sizeof(dfsstring), " dfs:%d %s", acl->dfs, acl->cell))) {
355 fprintf (stderr, "dfsstring - cannot be populated");
361 if( FAILED(StringCbPrintf(mydata, sizeof(mydata), "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus))) {
362 fprintf (stderr, "mydata - cannot be populated");
365 for (tp = acl->pluslist;tp;tp=tp->next) {
366 if( FAILED(StringCbPrintf(tstring, sizeof(tstring), "%s %d\n", tp->name, tp->rights))) {
367 fprintf (stderr, "tstring - cannot be populated");
370 if( FAILED(StringCbCat(mydata, sizeof(mydata), tstring))) {
371 fprintf (stderr, "mydata - not enough space");
375 for (tp = acl->minuslist;tp;tp=tp->next) {
376 if( FAILED(StringCbPrintf(tstring, sizeof(tstring), "%s %d\n", tp->name, tp->rights))) {
377 fprintf (stderr, "tstring - cannot be populated");
380 if( FAILED(StringCbCat(mydata, sizeof(mydata), tstring))) {
381 fprintf (stderr, "mydata - not enough space");
389 * Check if a username is valid: If it contains only digits (or a
390 * negative sign), then it might be bad. If we know the cellname,
391 * then query the ptserver to see if the entry is recognized.
394 BadName(char *aname, char *cellname)
396 afs_int32 tc, code, id = 0;
399 for ( nm = aname; tc = *nm; nm++) {
400 /* all must be '-' or digit to be bad */
401 if (tc != '-' && (tc < '0' || tc > '9'))
408 /* Go to the PRDB and see if this all number username is valid */
409 cm_GetConfigDir(confDir, sizeof(confDir));
411 pr_Initialize(1, confDir, cellname);
412 code = pr_SNameToId(aname, &id);
416 /* 1=>Not-valid; 0=>Valid */
417 return ((!code && (id == ANONYMOUSID)) ? 1 : 0);