Windows: refactor fs acl funcs into fs_acl.c
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 4 Jun 2011 17:28:26 +0000 (13:28 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Tue, 7 Jun 2011 13:26:08 +0000 (06:26 -0700)
The ACL structure definitions and manipulation functions
were defined both in WINNT/afsd/fs.c and WINNT/client_exp/gui2fs.cpp.
Extract them to WINNT/afsd/fs_acl.c and refactor them so that a
single copy can be maintained for both modules.

The most significant change is to CleanAcl() which now accepts
a cellname instead of a file path.  By accepting a cellname the
ACL functionality is completely isolated from the path processing
and pioctl operations.

At the present time, fs.exe calls CleanAcl() with a cell name
and afs_shl_ext.dll does not.  All callers in fs.c have been updated
to use the new behavior.

gui2fs.cpp also comments functions that exist in the file but
have no caller.  These can be removed at a later date if they
are not required.

Change-Id: Ibc5f411c6410769bdfeaf9e37b6d39a64958baff
Reviewed-on: http://gerrit.openafs.org/4783
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

src/WINNT/afsd/NTMakefile
src/WINNT/afsd/fs.c
src/WINNT/afsd/fs_acl.c [new file with mode: 0644]
src/WINNT/afsd/fs_acl.h [new file with mode: 0644]
src/WINNT/afsd/symlink.c
src/WINNT/client_exp/NTMakefile
src/WINNT/client_exp/fs.h [deleted file]
src/WINNT/client_exp/gui2fs.cpp

index cd00e13..d364844 100644 (file)
@@ -35,6 +35,7 @@ INCFILES =\
        $(INCFILEDIR)\cm_user.h \
        $(INCFILEDIR)\cm_dns.h \
        $(INCFILEDIR)\cm_utils.h \
+        $(INCFILEDIR)\fs_acl.h \
        $(INCFILEDIR)\fs_utils.h \
        $(INCFILEDIR)\krb.h \
        $(INCFILEDIR)\krb_prot.h \
@@ -159,6 +160,7 @@ $(OUT)\cm_conn.obj: cm_conn.c
        $(C2OBJ) -DAFS_PTHREAD_ENV /Fo$@ $**
 
 FSOBJS=$(OUT)\fs.obj \
+       $(OUT)\fs_acl.obj \
        $(OUT)\fs_utils.obj \
        $(OUT)\cm_nls.obj \
        $(OUT)\parsemode.obj
index b3d3e13..affb940 100644 (file)
 
 #include "fs.h"
 #include "fs_utils.h"
+#include "fs_acl.h"
 #include "cmd.h"
 #include "afsd.h"
 #include "cm_ioctl.h"
 #include "parsemode.h"
 
-#define MAXNAME 100
 #define MAXINSIZE 1300    /* pioctl complains if data is larger than this */
 #define VMSGSIZE 128      /* size of msg buf in volume hdr */
 #define CELL_MAXNAMELEN                256
@@ -57,15 +57,10 @@ static char space[AFS_PIOCTL_MAXSIZE];
 static struct ubik_client *uclient;
 
 /* some forward references */
-static void ZapList (struct AclEntry *alist);
-
-static int PruneList (struct AclEntry **ae, int dfs);
-
-static int CleanAcl(struct Acl *aa, char *fname);
-
 static int SetVolCmd(struct cmd_syndesc *as, void *arock);
 
 static int GetCellName(char *cellNamep, struct afsconf_cell *infop);
+static afs_int32 GetCell(char *fname, char *cellname, size_t cell_len);
 
 static int VLDBInit(int noAuthFlag, struct afsconf_cell *infop);
 static int GetClientAddrsCmd(struct cmd_syndesc *asp, void *arock);
@@ -81,69 +76,6 @@ static int MiniDumpCmd(struct cmd_syndesc *asp, void *arock);
 static int rxInitDone = 0;
 
 /*
- * Character to use between name and rights in printed representation for
- * DFS ACL's.
- */
-#define DFS_SEPARATOR  ' '
-
-typedef char sec_rgy_name_t[1025];     /* A DCE definition */
-
-struct Acl {
-    int dfs;           /* Originally true if a dfs acl; now also the type
-                         * of the acl (1, 2, or 3, corresponding to object,
-                         * initial dir, or initial object). */
-    sec_rgy_name_t cell; /* DFS cell name */
-    int nplus;
-    int nminus;
-    struct AclEntry *pluslist;
-    struct AclEntry *minuslist;
-};
-
-struct AclEntry {
-    struct AclEntry *next;
-    char name[MAXNAME];
-    afs_int32 rights;
-};
-
-static void
-ZapAcl (struct Acl *acl)
-{
-    if (!acl)
-        return;
-
-    ZapList(acl->pluslist);
-    ZapList(acl->minuslist);
-    free(acl);
-}
-
-/*
- * Mods for the AFS/DFS protocol translator.
- *
- * DFS rights. It's ugly to put these definitions here, but they
- * *cannot* change, because they're part of the wire protocol.
- * In any event, the protocol translator will guarantee these
- * assignments for AFS cache managers.
- */
-#define DFS_READ          0x01
-#define DFS_WRITE         0x02
-#define DFS_EXECUTE       0x04
-#define DFS_CONTROL       0x08
-#define DFS_INSERT        0x10
-#define DFS_DELETE        0x20
-
-/* the application definable ones (backwards from AFS) */
-#define DFS_USR0 0x80000000      /* "A" bit */
-#define DFS_USR1 0x40000000      /* "B" bit */
-#define DFS_USR2 0x20000000      /* "C" bit */
-#define DFS_USR3 0x10000000      /* "D" bit */
-#define DFS_USR4 0x08000000      /* "E" bit */
-#define DFS_USR5 0x04000000      /* "F" bit */
-#define DFS_USR6 0x02000000      /* "G" bit */
-#define DFS_USR7 0x01000000      /* "H" bit */
-#define DFS_USRALL     (DFS_USR0 | DFS_USR1 | DFS_USR2 | DFS_USR3 |\
-                        DFS_USR4 | DFS_USR5 | DFS_USR6 | DFS_USR7)
-
-/*
  * Offset of -id switch in command structure for various commands.
  * The -if switch is the next switch always.
  */
@@ -255,10 +187,6 @@ PRights(afs_int32 arights, int dfs)
     return 0;
 }
 
-                                /* added relative add resp. delete    */
-                                /* (so old add really means to set)   */
-enum rtype { add, destroy, deny, reladd, reldel };
-
 static afs_int32
 Convert(char *arights, int dfs, enum rtype *rtypep)
 {
@@ -391,17 +319,6 @@ Convert(char *arights, int dfs, enum rtype *rtypep)
     return mode;
 }
 
-static struct AclEntry *
-FindList (struct AclEntry *alist, char *aname)
-{
-    while (alist) {
-        if (!strcasecmp(alist->name, aname))
-            return alist;
-        alist = alist->next;
-    }
-    return 0;
-}
-
 /* if no parm specified in a particular slot, set parm to be "." instead */
 static void
 SetDotDefault(struct cmd_item **aitemp)
@@ -424,248 +341,6 @@ SetDotDefault(struct cmd_item **aitemp)
     *aitemp = ti;
 }
 
-static void
-ChangeList (struct Acl *al, afs_int32 plus, char *aname, afs_int32 arights,
-           enum rtpe *artypep)
-{
-    struct AclEntry *tlist;
-    tlist = (plus ? al->pluslist : al->minuslist);
-    tlist = FindList (tlist, aname);
-    if (tlist) {
-        /* Found the item already in the list. */
-                                /* modify rights in case of reladd    */
-                                /* and reladd only, use standard -    */
-                                /* add, ie. set - otherwise           */
-        if ( artypep == NULL )
-            tlist->rights = arights;
-        else if ( *artypep == reladd )
-            tlist->rights |= arights;
-        else if ( *artypep == reldel )
-            tlist->rights &= ~arights;
-        else
-            tlist->rights = arights;
-
-        if (plus)
-            al->nplus -= PruneList(&al->pluslist, al->dfs);
-        else
-            al->nminus -= PruneList(&al->minuslist, al->dfs);
-        return;
-    }
-    if ( artypep != NULL && *artypep == reldel )
-                                /* can't reduce non-existing rights   */
-        return;
-
-    /* Otherwise we make a new item and plug in the new data. */
-    tlist = (struct AclEntry *) malloc(sizeof (struct AclEntry));
-    assert(tlist);
-    if( FAILED(StringCbCopy(tlist->name, sizeof(tlist->name), aname))) {
-       fprintf (stderr, "name - not enough space");
-        exit(1);
-    }
-    tlist->rights = arights;
-    if (plus) {
-        tlist->next = al->pluslist;
-        al->pluslist = tlist;
-        al->nplus++;
-        if (arights == 0 || arights == -1)
-           al->nplus -= PruneList(&al->pluslist, al->dfs);
-    } else {
-        tlist->next = al->minuslist;
-        al->minuslist = tlist;
-        al->nminus++;
-        if (arights == 0)
-            al->nminus -= PruneList(&al->minuslist, al->dfs);
-    }
-}
-
-static void
-ZapList (struct AclEntry *alist)
-{
-    struct AclEntry *tp, *np;
-    for (tp = alist; tp; tp = np) {
-        np = tp->next;
-        free(tp);
-    }
-}
-
-static int
-PruneList (struct AclEntry **ae, int dfs)
-{
-    struct AclEntry **lp;
-    struct AclEntry *te, *ne;
-    afs_int32 ctr;
-    ctr = 0;
-    lp = ae;
-    for(te = *ae;te;te=ne) {
-        if ((!dfs && te->rights == 0) || te->rights == -1) {
-            *lp = te->next;
-            ne = te->next;
-            free(te);
-            ctr++;
-       } else {
-            ne = te->next;
-            lp = &te->next;
-       }
-    }
-    return ctr;
-}
-
-static char *
-SkipLine (char *astr)
-{
-    while (*astr !='\n')
-        astr++;
-    astr++;
-    return astr;
-}
-
-/*
- * Create an empty acl, taking into account whether the acl pointed
- * to by astr is an AFS or DFS acl. Only parse this minimally, so we
- * can recover from problems caused by bogus ACL's (in that case, always
- * assume that the acl is AFS: for DFS, the user can always resort to
- * acl_edit, but for AFS there may be no other way out).
- */
-static struct Acl *
-EmptyAcl(char *astr)
-{
-    struct Acl *tp;
-    int junk;
-
-    tp = (struct Acl *)malloc(sizeof (struct Acl));
-    assert(tp);
-    tp->nplus = tp->nminus = 0;
-    tp->pluslist = tp->minuslist = 0;
-    tp->dfs = 0;
-#if _MSC_VER < 1400
-    if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
-        tp->dfs = 0;
-        tp->cell[0] = '\0';
-    }
-#else
-    if (astr == NULL || sscanf_s(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell, sizeof(tp->cell)) <= 0) {
-        tp->dfs = 0;
-        tp->cell[0] = '\0';
-    }
-#endif
-    return tp;
-}
-
-static struct Acl *
-ParseAcl (char *astr, int astr_size)
-{
-    int nplus, nminus, i, trights, ret;
-    size_t len;
-    char tname[MAXNAME];
-    struct AclEntry *first, *next, *last, *tl;
-    struct Acl *ta;
-
-    ta = EmptyAcl(NULL);
-    if( FAILED(StringCbLength(astr, astr_size, &len))) {
-        fprintf (stderr, "StringCbLength failure on astr");
-        exit(1);
-    }
-    if (astr == NULL || len == 0)
-        return ta;
-
-#if _MSC_VER < 1400
-    ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
-#else
-    ret = sscanf_s(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell, sizeof(ta->cell));
-#endif
-    if (ret <= 0) {
-        free(ta);
-        return NULL;
-    }
-    astr = SkipLine(astr);
-#if _MSC_VER < 1400
-    ret = sscanf(astr, "%d", &ta->nminus);
-#else
-    ret = sscanf_s(astr, "%d", &ta->nminus);
-#endif
-    if (ret <= 0) {
-        free(ta);
-        return NULL;
-    }
-    astr = SkipLine(astr);
-
-    nplus = ta->nplus;
-    nminus = ta->nminus;
-
-    last = 0;
-    first = 0;
-    for(i=0;i<nplus;i++) {
-#if _MSC_VER < 1400
-        ret = sscanf(astr, "%100s %d", tname, &trights);
-#else
-        ret = sscanf_s(astr, "%100s %d", tname, sizeof(tname), &trights);
-#endif
-        if (ret <= 0)
-            goto nplus_err;
-        astr = SkipLine(astr);
-        tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
-        if (tl == NULL)
-            goto nplus_err;
-        if (!first)
-            first = tl;
-        if( FAILED(StringCbCopy(tl->name, sizeof(tl->name), tname))) {
-            fprintf (stderr, "name - not enough space");
-            exit(1);
-        }
-        tl->rights = trights;
-        tl->next = 0;
-        if (last)
-            last->next = tl;
-        last = tl;
-    }
-    ta->pluslist = first;
-
-    last = 0;
-    first = 0;
-    for(i=0;i<nminus;i++) {
-#if _MSC_VER < 1400
-        ret = sscanf(astr, "%100s %d", tname, &trights);
-#else
-        ret = sscanf_s(astr, "%100s %d", tname, sizeof(tname), &trights);
-#endif
-        if (ret <= 0)
-            goto nminus_err;
-        astr = SkipLine(astr);
-        tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
-        if (tl == NULL)
-            goto nminus_err;
-        if (!first)
-            first = tl;
-        if( FAILED(StringCbCopy(tl->name, sizeof(tl->name), tname))) {
-            fprintf (stderr, "name - not enough space");
-            exit(1);
-        }
-        tl->rights = trights;
-        tl->next = 0;
-        if (last)
-            last->next = tl;
-        last = tl;
-    }
-    ta->minuslist = first;
-
-    return ta;
-
-  nminus_err:
-    for (;first; first = next) {
-        next = first->next;
-        free(first);
-    }
-    first = ta->pluslist;
-
-  nplus_err:
-    for (;first; first = next) {
-        next = first->next;
-        free(first);
-    }
-    free(ta);
-    return NULL;
-}
-
 static int
 PrintStatus(VolumeStatus *status, char *name, char *motd, char *offmsg)
 {
@@ -739,49 +414,6 @@ QuickPrintSpace(VolumeStatus *status, char *name)
     return 0;
 }
 
-static char *
-AclToString(struct Acl *acl)
-{
-    static char mydata[AFS_PIOCTL_MAXSIZE];
-    char tstring[AFS_PIOCTL_MAXSIZE];
-    char dfsstring[30];
-    struct AclEntry *tp;
-
-    if (acl->dfs) {
-        if( FAILED(StringCbPrintf(dfsstring, sizeof(dfsstring), " dfs:%d %s", acl->dfs, acl->cell))) {
-            fprintf (stderr, "dfsstring - cannot be populated");
-            exit(1);
-        }
-    } else {
-        dfsstring[0] = '\0';
-    }
-    if( FAILED(StringCbPrintf(mydata, sizeof(mydata), "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus))) {
-        fprintf (stderr, "mydata - cannot be populated");
-        exit(1);
-    }
-    for (tp = acl->pluslist;tp;tp=tp->next) {
-        if( FAILED(StringCbPrintf(tstring, sizeof(tstring), "%s %d\n", tp->name, tp->rights))) {
-            fprintf (stderr, "tstring - cannot be populated");
-            exit(1);
-        }
-        if( FAILED(StringCbCat(mydata, sizeof(mydata), tstring))) {
-            fprintf (stderr, "mydata - not enough space");
-            exit(1);
-        }
-    }
-    for (tp = acl->minuslist;tp;tp=tp->next) {
-        if( FAILED(StringCbPrintf(tstring, sizeof(tstring), "%s %d\n", tp->name, tp->rights))) {
-            fprintf (stderr, "tstring - cannot be populated");
-            exit(1);
-        }
-        if( FAILED(StringCbCat(mydata, sizeof(mydata), tstring))) {
-            fprintf (stderr, "mydata - not enough space");
-            exit(1);
-        }
-    }
-    return mydata;
-}
-
 static DWORD IsFreelance(void)
 {
     HKEY  parmKey;
@@ -813,6 +445,7 @@ SetACLCmd(struct cmd_syndesc *as, void *arock)
     int idf = getidf(as, parm_setacl_id);
     size_t len;
     int error = 0;
+    char cell[CELL_MAXNAMELEN];
 
     if (as->parms[2].items)
         clear = 1;
@@ -820,6 +453,13 @@ SetACLCmd(struct cmd_syndesc *as, void *arock)
         clear = 0;
     plusp = !(as->parms[3].items);
     for(ti=as->parms[0].items; ti;ti=ti->next) {
+        code = GetCell(ti->data, cell, sizeof(cell));
+       if (code) {
+           fs_Die(errno, ti->data);
+           error = 1;
+            continue;
+       }
+
         if ( fs_IsFreelanceRoot(ti->data) ) {
             fprintf(stderr,"%s: ACLs cannot be set on the Freelance root.afs volume.\n", pn);
             error = 1;
@@ -865,7 +505,7 @@ SetACLCmd(struct cmd_syndesc *as, void *arock)
             error = 1;
             continue;
         }
-       CleanAcl(ta, ti->data);
+       CleanAcl(ta, cell);
        for(ui=as->parms[1].items; ui; ui=ui->next->next) {
            enum rtype rtype;
            if (!ui->next) {
@@ -965,6 +605,7 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
     int idf = getidf(as, parm_copyacl_id);
     int error = 0;
     size_t len;
+    char cell[CELL_MAXNAMELEN];
 
     if (as->parms[2].items)
         clear=1;
@@ -981,11 +622,18 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
     fa = ParseAcl(space, AFS_PIOCTL_MAXSIZE);
     if (!fa) {
         fprintf(stderr,
-                 "fs: %s: invalid acl data returned from VIOCGETAL\n",
-                 as->parms[0].items->data);
+                 "%s: %s: invalid acl data returned from VIOCGETAL\n",
+                 pn, as->parms[0].items->data);
         return 1;
     }
-    CleanAcl(fa, as->parms[0].items->data);
+    code = GetCell(as->parms[0].items->data, cell, sizeof(cell));
+    if (code) {
+        fprintf(stderr,
+                "%s: %s: unable to obtain cell name\n",
+                pn, as->parms[0].items->data);
+        return 1;
+    }
+    CleanAcl(fa, cell);
     for (ti=as->parms[1].items; ti;ti=ti->next) {
        blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = idf;
@@ -1004,12 +652,20 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
             ta = ParseAcl(space, AFS_PIOCTL_MAXSIZE);
         if (!ta) {
             fprintf(stderr,
-                    "fs: %s: invalid acl data returned from VIOCGETAL\n",
-                     ti->data);
+                    "%s: %s: invalid acl data returned from VIOCGETAL\n",
+                     pn, ti->data);
             error = 1;
             continue;
         }
-       CleanAcl(ta, ti->data);
+        code = GetCell(ti->data, cell, sizeof(cell));
+        if (code) {
+            fprintf(stderr,
+                    "%s: %s: unable to obtain cell name\n",
+                     pn, ti->data);
+            error = 1;
+            continue;
+        }
+       CleanAcl(ta, cell);
        if (ta->dfs != fa->dfs) {
            fprintf(stderr,
                     "%s: incompatible file system types: acl not copied to %s; aborted\n",
@@ -1061,13 +717,13 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
 
 /* pioctl_utf8() call to get the cellname of a pathname */
 static afs_int32
-GetCell(char *fname, char *cellname)
+GetCell(char *fname, char *cellname, size_t cell_len)
 {
     afs_int32 code;
     struct ViceIoctl blob;
 
     blob.in_size = 0;
-    blob.out_size = CELL_MAXNAMELEN;
+    blob.out_size = cell_len;
     blob.out = cellname;
 
     code = pioctl_utf8(fname, VIOC_FILE_CELL_NAME, &blob, 1);
@@ -1076,84 +732,6 @@ GetCell(char *fname, char *cellname)
     return code;
 }
 
-/* Check if a username is valid: If it contains only digits (or a
- * negative sign), then it might be bad.  We then query the ptserver
- * to see.
- */
-static int
-BadName(char *aname, char *fname)
-{
-    afs_int32 tc, code, id;
-    char *nm;
-    char cell[CELL_MAXNAMELEN];
-    char confDir[257];
-
-    for ( nm = aname; tc = *nm; nm++) {
-       /* all must be '-' or digit to be bad */
-       if (tc != '-' && (tc < '0' || tc > '9'))
-            return 0;
-    }
-
-    /* Go to the PRDB and see if this all number username is valid */
-    code = GetCell(fname, cell);
-    if (code)
-        return 0;
-
-    cm_GetConfigDir(confDir, sizeof(confDir));
-
-    pr_Initialize(1, confDir, cell);
-    code = pr_SNameToId(aname, &id);
-    pr_End();
-
-    /* 1=>Not-valid; 0=>Valid */
-    return ((!code && (id == ANONYMOUSID)) ? 1 : 0);
-}
-
-
-/* clean up an access control list of its bad entries; return 1 if we made
-   any changes to the list, and 0 otherwise */
-static int
-CleanAcl(struct Acl *aa, char *fname)
-{
-    struct AclEntry *te, **le, *ne;
-    int changes;
-
-    /* Don't correct DFS ACL's for now */
-    if (aa->dfs)
-       return 0;
-
-    /* prune out bad entries */
-    changes = 0;           /* count deleted entries */
-    le = &aa->pluslist;
-    for(te = aa->pluslist; te; te=ne) {
-       ne = te->next;
-       if (BadName(te->name, fname)) {
-           /* zap this dude */
-           *le = te->next;
-           aa->nplus--;
-           free(te);
-           changes++;
-       } else {
-           le = &te->next;
-       }
-    }
-    le = &aa->minuslist;
-    for(te = aa->minuslist; te; te=ne) {
-       ne = te->next;
-       if (BadName(te->name, fname)) {
-           /* zap this dude */
-           *le = te->next;
-           aa->nminus--;
-           free(te);
-           changes++;
-       } else {
-           le = &te->next;
-       }
-    }
-    return changes;
-}
-
-
 /* clean up an acl to not have bogus entries */
 static int
 CleanACLCmd(struct cmd_syndesc *as, void *arock)
@@ -1166,6 +744,7 @@ CleanACLCmd(struct cmd_syndesc *as, void *arock)
     struct AclEntry *te;
     int error = 0;
     size_t len;
+    char cell[CELL_MAXNAMELEN];
 
     SetDotDefault(&as->parms[0].items);
     for(ti=as->parms[0].items; ti; ti=ti->next) {
@@ -2133,7 +1712,7 @@ MakeMountCmd(struct cmd_syndesc *as, void *arock)
        }
     } else {
        if (!cellName) {
-           code = GetCell(parent,space);
+           code = GetCell(parent, space, sizeof(space));
             if (code)
                 return 1;
         }
diff --git a/src/WINNT/afsd/fs_acl.c b/src/WINNT/afsd/fs_acl.c
new file mode 100644 (file)
index 0000000..e29705b
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * 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
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+#include <roken.h>
+
+#include <afs/stds.h>
+#include <afs/afs_consts.h>
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <winioctl.h>
+#include <winsock2.h>
+#include <nb30.h>
+
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <strsafe.h>
+#include <afs/afs_assert.h>
+#include <afs/ptserver.h>
+#include <afs/ptuser.h>
+
+
+#include "fs_acl.h"
+
+static int BadName(char *aname, char *cellname);
+
+void
+ZapAcl (struct Acl *acl)
+{
+    if (!acl)
+        return;
+
+    ZapList(acl->pluslist);
+    ZapList(acl->minuslist);
+    free(acl);
+}
+
+void
+ZapList (struct AclEntry *alist)
+{
+    struct AclEntry *tp, *np;
+    for (tp = alist; tp; tp = np) {
+        np = tp->next;
+        free(tp);
+    }
+}
+
+int
+PruneList (struct AclEntry **ae, int dfs)
+{
+    struct AclEntry **lp;
+    struct AclEntry *te, *ne;
+    afs_int32 ctr;
+    ctr = 0;
+    lp = ae;
+    for(te = *ae;te;te=ne) {
+        if ((!dfs && te->rights == 0) || te->rights == -1) {
+            *lp = te->next;
+            ne = te->next;
+            free(te);
+            ctr++;
+       } else {
+            ne = te->next;
+            lp = &te->next;
+       }
+    }
+    return ctr;
+}
+
+static char *
+SkipLine (char *astr)
+{
+    while (*astr !='\n')
+        astr++;
+    astr++;
+    return astr;
+}
+
+struct AclEntry *
+FindList (struct AclEntry *alist, char *aname)
+{
+    while (alist) {
+        if (!strcasecmp(alist->name, aname))
+            return alist;
+        alist = alist->next;
+    }
+    return 0;
+}
+
+void
+ChangeList (struct Acl *al, afs_int32 plus, char *aname, afs_int32 arights,
+           enum rtype *artypep)
+{
+    struct AclEntry *tlist;
+    tlist = (plus ? al->pluslist : al->minuslist);
+    tlist = FindList (tlist, aname);
+    if (tlist) {
+        /* Found the item already in the list. */
+                                /* modify rights in case of reladd    */
+                                /* and reladd only, use standard -    */
+                                /* add, ie. set - otherwise           */
+        if ( artypep == NULL )
+            tlist->rights = arights;
+        else if ( *artypep == reladd )
+            tlist->rights |= arights;
+        else if ( *artypep == reldel )
+            tlist->rights &= ~arights;
+        else
+            tlist->rights = arights;
+
+        if (plus)
+            al->nplus -= PruneList(&al->pluslist, al->dfs);
+        else
+            al->nminus -= PruneList(&al->minuslist, al->dfs);
+        return;
+    }
+    if ( artypep != NULL && *artypep == reldel )
+                                /* can't reduce non-existing rights   */
+        return;
+
+    /* Otherwise we make a new item and plug in the new data. */
+    tlist = (struct AclEntry *) malloc(sizeof (struct AclEntry));
+    assert(tlist);
+    if( FAILED(StringCbCopy(tlist->name, sizeof(tlist->name), aname))) {
+       fprintf (stderr, "name - not enough space");
+        exit(1);
+    }
+    tlist->rights = arights;
+    if (plus) {
+        tlist->next = al->pluslist;
+        al->pluslist = tlist;
+        al->nplus++;
+        if (arights == 0 || arights == -1)
+           al->nplus -= PruneList(&al->pluslist, al->dfs);
+    } else {
+        tlist->next = al->minuslist;
+        al->minuslist = tlist;
+        al->nminus++;
+        if (arights == 0)
+            al->nminus -= PruneList(&al->minuslist, al->dfs);
+    }
+}
+
+
+/*
+ * Create an empty acl, taking into account whether the acl pointed
+ * to by astr is an AFS or DFS acl. Only parse this minimally, so we
+ * can recover from problems caused by bogus ACL's (in that case, always
+ * assume that the acl is AFS: for DFS, the user can always resort to
+ * acl_edit, but for AFS there may be no other way out).
+ */
+struct Acl *
+EmptyAcl(char *astr)
+{
+    struct Acl *tp;
+    int junk;
+
+    tp = (struct Acl *)malloc(sizeof (struct Acl));
+    assert(tp);
+    tp->nplus = tp->nminus = 0;
+    tp->pluslist = tp->minuslist = 0;
+    tp->dfs = 0;
+#if _MSC_VER < 1400
+    if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
+        tp->dfs = 0;
+        tp->cell[0] = '\0';
+    }
+#else
+    if (astr == NULL || sscanf_s(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell, sizeof(tp->cell)) <= 0) {
+        tp->dfs = 0;
+        tp->cell[0] = '\0';
+    }
+#endif
+    return tp;
+}
+
+/* clean up an access control list of its bad entries; return 1 if we made
+   any changes to the list, and 0 otherwise */
+int
+CleanAcl(struct Acl *aa, char *cellname)
+{
+    struct AclEntry *te, **le, *ne;
+    int changes;
+
+    /* Don't correct DFS ACL's for now */
+    if (aa->dfs)
+       return 0;
+
+    /* prune out bad entries */
+    changes = 0;           /* count deleted entries */
+    le = &aa->pluslist;
+    for(te = aa->pluslist; te; te=ne) {
+       ne = te->next;
+       if (BadName(te->name, cellname)) {
+           /* zap this dude */
+           *le = te->next;
+           aa->nplus--;
+           free(te);
+           changes++;
+       } else {
+           le = &te->next;
+       }
+    }
+    le = &aa->minuslist;
+    for(te = aa->minuslist; te; te=ne) {
+       ne = te->next;
+       if (BadName(te->name, cellname)) {
+           /* zap this dude */
+           *le = te->next;
+           aa->nminus--;
+           free(te);
+           changes++;
+       } else {
+           le = &te->next;
+       }
+    }
+    return changes;
+}
+
+struct Acl *
+ParseAcl (char *astr, int astr_size)
+{
+    int nplus, nminus, i, trights, ret;
+    size_t len;
+    char tname[ACL_MAXNAME];
+    struct AclEntry *first, *next, *last, *tl;
+    struct Acl *ta;
+
+    ta = EmptyAcl(NULL);
+    if( FAILED(StringCbLength(astr, astr_size, &len))) {
+        fprintf (stderr, "StringCbLength failure on astr");
+        exit(1);
+    }
+    if (astr == NULL || len == 0)
+        return ta;
+
+#if _MSC_VER < 1400
+    ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
+#else
+    ret = sscanf_s(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell, sizeof(ta->cell));
+#endif
+    if (ret <= 0) {
+        free(ta);
+        return NULL;
+    }
+    astr = SkipLine(astr);
+#if _MSC_VER < 1400
+    ret = sscanf(astr, "%d", &ta->nminus);
+#else
+    ret = sscanf_s(astr, "%d", &ta->nminus);
+#endif
+    if (ret <= 0) {
+        free(ta);
+        return NULL;
+    }
+    astr = SkipLine(astr);
+
+    nplus = ta->nplus;
+    nminus = ta->nminus;
+
+    last = 0;
+    first = 0;
+    for(i=0;i<nplus;i++) {
+#if _MSC_VER < 1400
+        ret = sscanf(astr, "%100s %d", tname, &trights);
+#else
+        ret = sscanf_s(astr, "%100s %d", tname, sizeof(tname), &trights);
+#endif
+        if (ret <= 0)
+            goto nplus_err;
+        astr = SkipLine(astr);
+        tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
+        if (tl == NULL)
+            goto nplus_err;
+        if (!first)
+            first = tl;
+        if( FAILED(StringCbCopy(tl->name, sizeof(tl->name), tname))) {
+            fprintf (stderr, "name - not enough space");
+            exit(1);
+        }
+        tl->rights = trights;
+        tl->next = 0;
+        if (last)
+            last->next = tl;
+        last = tl;
+    }
+    ta->pluslist = first;
+
+    last = 0;
+    first = 0;
+    for(i=0;i<nminus;i++) {
+#if _MSC_VER < 1400
+        ret = sscanf(astr, "%100s %d", tname, &trights);
+#else
+        ret = sscanf_s(astr, "%100s %d", tname, sizeof(tname), &trights);
+#endif
+        if (ret <= 0)
+            goto nminus_err;
+        astr = SkipLine(astr);
+        tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
+        if (tl == NULL)
+            goto nminus_err;
+        if (!first)
+            first = tl;
+        if( FAILED(StringCbCopy(tl->name, sizeof(tl->name), tname))) {
+            fprintf (stderr, "name - not enough space");
+            exit(1);
+        }
+        tl->rights = trights;
+        tl->next = 0;
+        if (last)
+            last->next = tl;
+        last = tl;
+    }
+    ta->minuslist = first;
+
+    return ta;
+
+  nminus_err:
+    for (;first; first = next) {
+        next = first->next;
+        free(first);
+    }
+    first = ta->pluslist;
+
+  nplus_err:
+    for (;first; first = next) {
+        next = first->next;
+        free(first);
+    }
+    free(ta);
+    return NULL;
+}
+
+char *
+AclToString(struct Acl *acl)
+{
+    static char mydata[AFS_PIOCTL_MAXSIZE];
+    char tstring[AFS_PIOCTL_MAXSIZE];
+    char dfsstring[30];
+    struct AclEntry *tp;
+
+    if (acl->dfs) {
+        if( FAILED(StringCbPrintf(dfsstring, sizeof(dfsstring), " dfs:%d %s", acl->dfs, acl->cell))) {
+            fprintf (stderr, "dfsstring - cannot be populated");
+            exit(1);
+        }
+    } else {
+        dfsstring[0] = '\0';
+    }
+    if( FAILED(StringCbPrintf(mydata, sizeof(mydata), "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus))) {
+        fprintf (stderr, "mydata - cannot be populated");
+        exit(1);
+    }
+    for (tp = acl->pluslist;tp;tp=tp->next) {
+        if( FAILED(StringCbPrintf(tstring, sizeof(tstring), "%s %d\n", tp->name, tp->rights))) {
+            fprintf (stderr, "tstring - cannot be populated");
+            exit(1);
+        }
+        if( FAILED(StringCbCat(mydata, sizeof(mydata), tstring))) {
+            fprintf (stderr, "mydata - not enough space");
+            exit(1);
+        }
+    }
+    for (tp = acl->minuslist;tp;tp=tp->next) {
+        if( FAILED(StringCbPrintf(tstring, sizeof(tstring), "%s %d\n", tp->name, tp->rights))) {
+            fprintf (stderr, "tstring - cannot be populated");
+            exit(1);
+        }
+        if( FAILED(StringCbCat(mydata, sizeof(mydata), tstring))) {
+            fprintf (stderr, "mydata - not enough space");
+            exit(1);
+        }
+    }
+    return mydata;
+}
+
+/*
+ * Check if a username is valid: If it contains only digits (or a
+ * negative sign), then it might be bad.  If we know the cellname,
+ * then query the ptserver to see if the entry is recognized.
+ */
+static int
+BadName(char *aname, char *cellname)
+{
+    afs_int32 tc, code, id = 0;
+    char *nm;
+
+    for ( nm = aname; tc = *nm; nm++) {
+       /* all must be '-' or digit to be bad */
+       if (tc != '-' && (tc < '0' || tc > '9'))
+            return 0;
+    }
+
+    if (cellname) {
+        char confDir[257];
+
+        /* Go to the PRDB and see if this all number username is valid */
+        cm_GetConfigDir(confDir, sizeof(confDir));
+
+        pr_Initialize(1, confDir, cellname);
+        code = pr_SNameToId(aname, &id);
+        pr_End();
+    }
+
+    /* 1=>Not-valid; 0=>Valid */
+    return ((!code && (id == ANONYMOUSID)) ? 1 : 0);
+}
+
+
diff --git a/src/WINNT/afsd/fs_acl.h b/src/WINNT/afsd/fs_acl.h
new file mode 100644 (file)
index 0000000..78721be
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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
+ */
+
+#ifndef AFS_FS_ACL_H
+#define AFS_FS_ACL_H
+
+#define ACL_MAXNAME 100
+
+
+/*
+ * Character to use between name and rights in printed representation for
+ * DFS ACL's.
+ */
+#define DFS_SEPARATOR  ' '
+
+typedef char sec_rgy_name_t[1025];     /* A DCE definition */
+
+struct Acl {
+    int dfs;           /* Originally true if a dfs acl; now also the type
+                         * of the acl (1, 2, or 3, corresponding to object,
+                         * initial dir, or initial object). */
+    sec_rgy_name_t cell; /* DFS cell name */
+    int nplus;
+    int nminus;
+    struct AclEntry *pluslist;
+    struct AclEntry *minuslist;
+};
+
+struct AclEntry {
+    struct AclEntry *next;
+    char name[ACL_MAXNAME];
+    afs_int32 rights;
+};
+
+/*
+ * Mods for the AFS/DFS protocol translator.
+ *
+ * DFS rights. It's ugly to put these definitions here, but they
+ * *cannot* change, because they're part of the wire protocol.
+ * In any event, the protocol translator will guarantee these
+ * assignments for AFS cache managers.
+ */
+#define DFS_READ          0x01
+#define DFS_WRITE         0x02
+#define DFS_EXECUTE       0x04
+#define DFS_CONTROL       0x08
+#define DFS_INSERT        0x10
+#define DFS_DELETE        0x20
+
+/* the application definable ones (backwards from AFS) */
+#define DFS_USR0 0x80000000      /* "A" bit */
+#define DFS_USR1 0x40000000      /* "B" bit */
+#define DFS_USR2 0x20000000      /* "C" bit */
+#define DFS_USR3 0x10000000      /* "D" bit */
+#define DFS_USR4 0x08000000      /* "E" bit */
+#define DFS_USR5 0x04000000      /* "F" bit */
+#define DFS_USR6 0x02000000      /* "G" bit */
+#define DFS_USR7 0x01000000      /* "H" bit */
+#define DFS_USRALL     (DFS_USR0 | DFS_USR1 | DFS_USR2 | DFS_USR3 |\
+                        DFS_USR4 | DFS_USR5 | DFS_USR6 | DFS_USR7)
+
+/* added relative add resp. delete    */
+/* (so old add really means to set)   */
+enum rtype { add, destroy, deny, reladd, reldel };
+
+extern void ZapList(struct AclEntry *alist);
+
+extern void ZapAcl(struct Acl *acl);
+
+extern int PruneList(struct AclEntry **ae, int dfs);
+
+extern int CleanAcl(struct Acl *aa, char *cellname);
+
+extern struct Acl *EmptyAcl(char *astr);
+
+extern struct Acl *ParseAcl (char *astr, int astr_size);
+
+extern char *AclToString(struct Acl *acl);
+
+extern void ChangeList (struct Acl *al, afs_int32 plus, char *aname, afs_int32 arights);
+
+extern struct AclEntry *FindList (struct AclEntry *alist, char *aname);
+
+
+#endif
index ec3ce40..81cd572 100644 (file)
@@ -74,7 +74,6 @@ ListLinkCmd(struct cmd_syndesc *as, void *arock)
             continue;
         }
 
-
        /*
         * Find rightmost slash, if any.
         */
index 7c14c19..4dae2d1 100644 (file)
@@ -35,6 +35,7 @@ DLLOBJS =\
         $(OUT)\cm_nls.obj \
        $(OUT)\copy_acl_dlg.obj \
        $(OUT)\down_servers_dlg.obj \
+        $(OUT)\fs_acl.obj \
        $(OUT)\fs_utils.obj \
        $(OUT)\gui2fs.obj \
        $(OUT)\help.obj \
@@ -58,8 +59,11 @@ DLLOBJS =\
 
 AFSD = ..\afsd
 
+$(OUT)\fs_acl.obj: $(AFSD)\fs_acl.c
+       $(C2OBJ) -UUNICODE -U_UNICODE $**
+
 $(OUT)\fs_utils.obj: $(AFSD)\fs_utils.c
-       $(C2OBJ) -UUNICODE -U_UNICODE -I$(DESTDIR)\include\rx $**
+       $(C2OBJ) -UUNICODE -U_UNICODE $**
 
 $(OUT)\cm_nls.obj: $(AFSD)\cm_nls.c
        $(C2OBJ)  -UUNICODE -U_UNICODE $**
diff --git a/src/WINNT/client_exp/fs.h b/src/WINNT/client_exp/fs.h
deleted file mode 100644 (file)
index 4cc1b6b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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
- */
-
-#ifndef __FS_H_ENV__
-#define __FS_H_ENV__ 1
-
-/* some forward references */
-extern void ZapList(struct AclEntry *);
-
-extern void ZapAcl(struct Acl *);
-
-extern int PruneList (struct AclEntry **, int);
-
-extern void ChangeList(struct Acl *, long, char *, long);
-
-extern int CleanAcl(struct Acl *);
-
-extern void Die(int, char *);
-
-static int SetVolCmd(struct cmd_syndesc *);
-
-#endif /* FS_H_ENV */
index a404acd..02c0a48 100644 (file)
@@ -32,8 +32,8 @@ extern "C" {
 
 extern "C" {
 #include <rx/rx_globals.h>
-#include "fs.h"
 #include "fs_utils.h"
+#include "fs_acl.h"
 #include <afs/afsint.h>
 #include <afs/afs_consts.h>
 #include <afs/cellconfig.h>
@@ -52,6 +52,13 @@ extern "C" {
 #define STRSAFE_NO_DEPRECATE
 #include <strsafe.h>
 
+/*
+ * the NO_CALLER symbol is used to document functions
+ * that are present in this file but have no caller
+ */
+#define NO_CALLER
+
+
 #define PCCHAR(str)            ((char *)(const char *)(str))
 #define VL_NOENT                (363524L)
 
@@ -138,7 +145,8 @@ public:
     }
 };
 
-long pioctl_T(const CString& path, long opcode, struct ViceIoctl * blob, int follow)
+long
+pioctl_T(const CString& path, long opcode, struct ViceIoctl * blob, int follow)
 {
     CStringUtf8 upath(path);
 
@@ -151,9 +159,7 @@ long pioctl_T(const CString& path, long opcode, struct ViceIoctl * blob, int fol
 #define Utf8ToCString(cs) (cs)
 #endif
 
-
-
-static int
+static int NO_CALLER
 VLDBInit(int noAuthFlag, struct afsconf_cell *info)
 {
     afs_int32 code;
@@ -202,7 +208,8 @@ CString StripPath(CString& strPath)
     return strFile;
 }
 
-CStringArray& StripPath(CStringArray& files)
+CStringArray&
+StripPath(CStringArray& files)
 {
     for (int i = 0; i < files.GetSize(); i++)
         files[i] = StripPath(files[i]);
@@ -210,7 +217,8 @@ CStringArray& StripPath(CStringArray& files)
     return files;
 }
 
-void Flush(const CStringArray& files)
+void
+Flush(const CStringArray& files)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -235,7 +243,8 @@ void Flush(const CStringArray& files)
         ShowMessageBox(IDS_FLUSH_OK, MB_ICONINFORMATION, IDS_FLUSH_OK);
 }
 
-void FlushVolume(const CStringArray& files)
+void
+FlushVolume(const CStringArray& files)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -257,7 +266,8 @@ void FlushVolume(const CStringArray& files)
         ShowMessageBox(IDS_FLUSH_VOLUME_OK, MB_ICONINFORMATION, IDS_FLUSH_VOLUME_OK);
 }
 
-void WhichCell(CStringArray& files)
+void NO_CALLER
+WhichCell(CStringArray& files)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -296,7 +306,8 @@ void WhichCell(CStringArray& files)
     dlg.DoModal();
 }
 
-void WSCellCmd()
+void NO_CALLER
+WSCellCmd(void)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -310,14 +321,14 @@ void WSCellCmd()
 
     code = pioctl((char *) 0, VIOC_GET_WS_CELL, &blob, 1);
 
-    if (code) {
-        //Die(errno, (char *) 0);
-    }
-    //else
-    //printf("This workstation belongs to cell '%s'\n", space);
+    /*
+     * Cell name is left in 'space' as side effect.
+     * At present no callers of this function.
+     */
 }
 
-BOOL CheckVolumes()
+BOOL NO_CALLER
+CheckVolumes(void)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -335,7 +346,8 @@ BOOL CheckVolumes()
     return TRUE;
 }
 
-void SetCacheSizeCmd(LONG nNewCacheSize)
+void NO_CALLER
+SetCacheSizeCmd(LONG nNewCacheSize)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -347,13 +359,12 @@ void SetCacheSizeCmd(LONG nNewCacheSize)
     blob.out_size = 0;
 
     code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
-    //if (code)
-    // Die(errno, (char *) 0);
-    //else
-    // printf("New cache size set.\n");
+
+    /* error handling? */
 }
 
-void WhereIs(CStringArray& files)
+void NO_CALLER
+WhereIs(CStringArray& files)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -443,7 +454,8 @@ CMtoUNIXerror(int cm_code)
     }
 }
 
-CString GetAfsError(int code, const TCHAR *filename)
+CString
+GetAfsError(int code, const TCHAR *filename)
 {
     CString strMsg;
 
@@ -479,30 +491,8 @@ CString GetAfsError(int code, const TCHAR *filename)
 }
 
 
-/************************************************************************
-************************** ACL Code *************************************
-************************************************************************/
-
-typedef char sec_rgy_name_t[1025];     /* A DCE definition */
-
-struct AclEntry {
-    struct AclEntry *next;
-    char name[MAXNAME];
-    LONG rights;
-};
-
-struct Acl {
-    int dfs;                   //      Originally true if a dfs acl; now also the type
-                                //     of the acl (1, 2, or 3, corresponding to object,
-                               //      initial dir, or initial object).
-    sec_rgy_name_t cell;       //      DFS cell name
-    int nplus;
-    int nminus;
-    struct AclEntry *pluslist;
-    struct AclEntry *minuslist;
-};
-
-int foldcmp (char *a, char *b)
+static int
+foldcmp (char *a, char *b)
 {
     char t, u;
     while (1) {
@@ -515,70 +505,8 @@ int foldcmp (char *a, char *b)
     }
 }
 
-extern "C" void ZapList(struct AclEntry *alist)
-{
-    struct AclEntry *tp, *np;
-
-    for (tp = alist; tp; tp = np) {
-        np = tp->next;
-        free(tp);
-    }
-}
-
-extern "C" void ZapAcl (struct Acl *acl)
-{
-    ZapList(acl->pluslist);
-    ZapList(acl->minuslist);
-    free(acl);
-}
-
-extern "C" int PruneList (struct AclEntry **ae, int dfs)
-{
-    struct AclEntry **lp = ae;
-    struct AclEntry *te, *ne;
-    LONG ctr = 0;
-
-    for (te = *ae; te; te = ne) {
-        if ((!dfs && te->rights == 0) || te->rights == -1) {
-            *lp = te->next;
-            ne = te->next;
-            free(te);
-            ctr++;
-        }
-        else {
-            ne = te->next;
-            lp = &te->next;
-        }
-    }
-
-    return ctr;
-}
-
-char *SkipLine (char *astr)
-{
-    while (*astr != '\n')
-        astr++;
-
-    astr++;
-
-    return astr;
-}
-
-/* tell if a name is 23 or -45 (digits or minus digits), which are bad names we must prune */
-static int BadName(char *aname)
-{
-    int tc;
-
-    /* all must be '-' or digit to be bad */
-    while (tc = *aname++) {
-        if ((tc != '-') && (tc < '0' || tc > '9'))
-            return 0;
-    }
-
-    return 1;
-}
-
-CString GetRightsString(LONG arights, int dfs)
+CString
+GetRightsString(LONG arights, int dfs)
 {
     CString str;
 
@@ -606,33 +534,8 @@ CString GetRightsString(LONG arights, int dfs)
     return str;
 }
 
-char *AclToString(struct Acl *acl)
-{
-    static char mydata[AFS_PIOCTL_MAXSIZE];
-    char tstring[AFS_PIOCTL_MAXSIZE];
-    char dfsstring[30];
-    struct AclEntry *tp;
-
-    if (acl->dfs)
-        sprintf(dfsstring, " dfs:%d %s", acl->dfs, acl->cell);
-    else
-        dfsstring[0] = '\0';
-    sprintf(mydata, "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus);
-
-    for(tp = acl->pluslist; tp; tp = tp->next) {
-        sprintf(tstring, "%s %d\n", tp->name, tp->rights);
-        strcat(mydata, tstring);
-    }
-
-    for(tp = acl->minuslist; tp; tp = tp->next) {
-        sprintf(tstring, "%s %d\n", tp->name, tp->rights);
-        strcat(mydata, tstring);
-    }
-
-    return mydata;
-}
-
-struct Acl *EmptyAcl(const CString& strCellName)
+struct Acl *
+EmptyAcl(const CString& strCellName)
 {
     struct Acl *tp;
     CStringUtf8 ustrCell(strCellName);
@@ -646,158 +549,8 @@ struct Acl *EmptyAcl(const CString& strCellName)
     return tp;
 }
 
-struct Acl *EmptyAcl(char *astr)
-{
-    struct Acl *tp;
-    int junk;
-
-    tp = (struct Acl *)malloc(sizeof (struct Acl));
-    tp->nplus = tp->nminus = 0;
-    tp->pluslist = tp->minuslist = 0;
-    tp->dfs = 0;
-    if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
-        tp->dfs = 0;
-        tp->cell[0] = '\0';
-    }
-    return tp;
-}
-
-struct Acl *
-ParseAcl (char *astr)
-{
-    int nplus, nminus, i, trights, ret;
-    char tname[MAXNAME];
-    struct AclEntry *first, *next, *last, *tl;
-    struct Acl *ta;
-
-    ta = EmptyAcl(NULL);
-    if (astr == NULL || strlen(astr) == 0)
-        return ta;
-
-    ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
-    if (ret <= 0) {
-        free(ta);
-        return NULL;
-    }
-    astr = SkipLine(astr);
-    ret = sscanf(astr, "%d", &ta->nminus);
-    if (ret <= 0) {
-        free(ta);
-        return NULL;
-    }
-    astr = SkipLine(astr);
-
-    nplus = ta->nplus;
-    nminus = ta->nminus;
-
-    last = 0;
-    first = 0;
-    for(i=0;i<nplus;i++) {
-        ret = sscanf(astr, "%100s %d", tname, &trights);
-        if (ret <= 0)
-            goto nplus_err;
-        astr = SkipLine(astr);
-        tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
-        if (tl == NULL)
-            goto nplus_err;
-        if (!first)
-            first = tl;
-        strcpy(tl->name, tname);
-        tl->rights = trights;
-        tl->next = 0;
-        if (last)
-            last->next = tl;
-        last = tl;
-    }
-    ta->pluslist = first;
-
-    last = 0;
-    first = 0;
-    for(i=0;i<nminus;i++) {
-        ret = sscanf(astr, "%100s %d", tname, &trights);
-        if (ret <= 0)
-            goto nminus_err;
-        astr = SkipLine(astr);
-        tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
-        if (tl == NULL)
-            goto nminus_err;
-        if (!first)
-            first = tl;
-        strcpy(tl->name, tname);
-        tl->rights = trights;
-        tl->next = 0;
-        if (last)
-            last->next = tl;
-        last = tl;
-    }
-    ta->minuslist = first;
-
-    return ta;
-
-  nminus_err:
-    for (;first; first = next) {
-        next = first->next;
-        free(first);
-    }
-    first = ta->pluslist;
-
-  nplus_err:
-    for (;first; first = next) {
-        next = first->next;
-        free(first);
-    }
-    free(ta);
-    return NULL;
-}
-
-/* clean up an access control list of its bad entries; return 1 if we made
-   any changes to the list, and 0 otherwise */
-extern "C" int CleanAcl(struct Acl *aa)
-{
-    struct AclEntry *te, **le, *ne;
-    int changes;
-
-    HOURGLASS hourglass;
-
-    /* Don't correct DFS ACL's for now */
-    if (aa->dfs)
-        return 0;
-
-    /* prune out bad entries */
-    changes = 0;           /* count deleted entries */
-    le = &aa->pluslist;
-    for(te = aa->pluslist; te; te = ne) {
-        ne = te->next;
-        if (BadName(te->name)) {
-            /* zap this dude */
-            *le = te->next;
-            aa->nplus--;
-            free(te);
-            changes++;
-        }
-        else
-            le = &te->next;
-    }
-
-    le = &aa->minuslist;
-
-    for(te = aa->minuslist; te; te = ne) {
-        ne = te->next;
-        if (BadName(te->name)) {
-            /* zap this dude */
-            *le = te->next;
-            aa->nminus--;
-            free(te);
-            changes++;
-        }
-        else
-            le = &te->next;
-    }
-
-    return changes;
-}
-
-void CleanACL(CStringArray& names)
+void
+CleanACL(CStringArray& names)
 {
     LONG code;
     struct Acl *ta;
@@ -819,7 +572,7 @@ void CleanACL(CStringArray& names)
             continue;
         }
 
-        ta = ParseAcl(space);
+        ta = ParseAcl(space, AFS_PIOCTL_MAXSIZE);
         if (ta == NULL) {
             ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
             continue;
@@ -829,7 +582,7 @@ void CleanACL(CStringArray& names)
             continue;
         }
 
-        changes = CleanAcl(ta);
+        changes = CleanAcl(ta, NULL);
         if (!changes)
             continue;
 
@@ -853,7 +606,8 @@ void CleanACL(CStringArray& names)
 }
 
 // Derived from fs.c's ListAclCmd
-BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
+BOOL
+GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
 {
     LONG code;
     struct Acl *ta;
@@ -873,7 +627,7 @@ BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& str
         return FALSE;
     }
 
-    ta = ParseAcl(space);
+    ta = ParseAcl(space, AFS_PIOCTL_MAXSIZE);
     if (ta == NULL) {
         ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
         return FALSE;
@@ -905,7 +659,8 @@ BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& str
     return TRUE;
 }
 
-struct AclEntry *FindList(struct AclEntry *pCurEntry, const char *entryName)
+struct AclEntry *
+FindList(struct AclEntry *pCurEntry, const char *entryName)
 {
     while (pCurEntry) {
         if (!foldcmp(pCurEntry->name, PCCHAR(entryName)))
@@ -916,7 +671,8 @@ struct AclEntry *FindList(struct AclEntry *pCurEntry, const char *entryName)
     return 0;
 }
 
-void ChangeList(struct Acl *pAcl, BYTE bNormalRights, const CString & entryName, LONG nEntryRights)
+void
+ChangeList(struct Acl *pAcl, BYTE bNormalRights, const CString & entryName, LONG nEntryRights)
 {
     ASSERT(pAcl);
     ASSERT(entryName);
@@ -962,9 +718,8 @@ void ChangeList(struct Acl *pAcl, BYTE bNormalRights, const CString & entryName,
     }
 }
 
-enum rtype {add, destroy, deny};
-
-static LONG Convert(const CString& strRights, int dfs, enum rtype *rtypep)
+static LONG
+Convert(const CString& strRights, int dfs, enum rtype *rtypep)
 {
     int i, len;
     LONG mode;
@@ -1005,7 +760,8 @@ static LONG Convert(const CString& strRights, int dfs, enum rtype *rtypep)
     return mode;
 }
 
-BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
+BOOL
+SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -1049,7 +805,8 @@ BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArr
     return (code == 0);
 }
 
-BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
+BOOL
+CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -1072,14 +829,14 @@ BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringA
     if (bClear)
         pToAcl = EmptyAcl(space);
     else
-        pToAcl = ParseAcl(space);
+        pToAcl = ParseAcl(space, AFS_PIOCTL_MAXSIZE);
 
     if (pToAcl == NULL) {
         ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
         return FALSE;
     }
 
-    CleanAcl(pToAcl);
+    CleanAcl(pToAcl, NULL);
 
     if (pToAcl->dfs) {
         ShowMessageBox(IDS_NO_DFS_COPY_ACL, MB_ICONERROR, IDS_NO_DFS_COPY_ACL, strToDir);
@@ -1124,7 +881,8 @@ BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringA
     return TRUE;
 }
 
-CString ParseMountPoint(const CString strFile, CString strMountPoint)
+CString
+ParseMountPoint(const CString strFile, CString strMountPoint)
 {
     CString strType;
     CString strVolume;
@@ -1148,7 +906,8 @@ CString ParseMountPoint(const CString strFile, CString strMountPoint)
     return strMountPointInfo;
 }
 
-CString ParseSymlink(const CString strFile, CString strSymlink)
+CString
+ParseSymlink(const CString strFile, CString strSymlink)
 {
     CString strSymlinkInfo;
 
@@ -1157,7 +916,8 @@ CString ParseSymlink(const CString strFile, CString strSymlink)
     return strSymlinkInfo;
 }
 
-BOOL IsPathInAfs(const CString & strPath)
+BOOL
+IsPathInAfs(const CString & strPath)
 {
     struct ViceIoctl blob;
     cm_ioctlQueryOptions_t options;
@@ -1199,7 +959,8 @@ IsFreelanceRoot(const CString& apath)
     return 1;   /* assume it is because it is more restrictive that way */
 }
 
-static const char * NetbiosName(void)
+static const char *
+NetbiosName(void)
 {
     static char buffer[1024] = "AFS";
     HKEY  parmKey;
@@ -1220,7 +981,8 @@ static const char * NetbiosName(void)
     return buffer;
 }
 
-static void FixNetbiosPath(CString& path)
+static void
+FixNetbiosPath(CString& path)
 {
     if (!IsPathInAfs(path)) {
         CString nbroot;
@@ -1240,7 +1002,8 @@ static void FixNetbiosPath(CString& path)
 
 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
 
-static BOOL IsAdmin (void)
+static BOOL
+IsAdmin (void)
 {
     static BOOL fAdmin = FALSE;
     static BOOL fTested = FALSE;
@@ -1373,7 +1136,8 @@ static BOOL IsAdmin (void)
     return fAdmin;
 }
 
-CString Parent(const CString& path)
+CString
+Parent(const CString& path)
 {
     int last_slash = path.ReverseFind(_T('\\'));
 
@@ -1392,7 +1156,8 @@ CString Parent(const CString& path)
     }
     }
 
-CString LastComponent(const CString& path)
+CString
+LastComponent(const CString& path)
 {
     int last_slash = path.ReverseFind(_T('\\'));
 
@@ -1433,7 +1198,8 @@ GetCell(const CString & path)
 }
 
 
-BOOL ListMount(CStringArray& files)
+BOOL
+ListMount(CStringArray& files)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -1557,39 +1323,8 @@ MakeMount(const CString& strDir,
     return TRUE;
 }
 
-/*
-*/
-long fs_ExtractDriveLetter(const char *inPathp, char *outPathp)
-{
-    if (inPathp[0] != 0 && inPathp[1] == ':') {
-        /* there is a drive letter */
-        *outPathp++ = *inPathp++;
-        *outPathp++ = *inPathp++;
-        *outPathp++ = 0;
-    }
-    else *outPathp = 0;
-
-    return 0;
-}
-
-/* strip the drive letter from a component */
-long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize)
-{
-    char tempBuffer[1000];
-    strcpy(tempBuffer, inPathp);
-    if (tempBuffer[0] != 0 && tempBuffer[1] == ':') {
-        /* drive letter present */
-        strcpy(outPathp, tempBuffer+2);
-    }
-    else {
-        /* no drive letter present */
-        strcpy(outPathp, tempBuffer);
-    }
-    return 0;
-}
-
-
-BOOL RemoveSymlink(const CString& strName)
+BOOL
+RemoveSymlink(const CString& strName)
 {
     BOOL error = FALSE;
     INT code=0;
@@ -1626,7 +1361,8 @@ BOOL RemoveSymlink(const CString& strName)
     return (code == 0);
 }
 
-BOOL IsSymlink(const CString& strName)
+BOOL
+IsSymlink(const CString& strName)
 {
     struct ViceIoctl blob;
     int code;
@@ -1652,7 +1388,8 @@ BOOL IsSymlink(const CString& strName)
 }
 
 
-BOOL IsMountPoint(const CString& path)
+BOOL
+IsMountPoint(const CString& path)
 {
     LONG code = 0;
     struct ViceIoctl blob;
@@ -1684,7 +1421,8 @@ BOOL IsMountPoint(const CString& path)
  *         (or ``.'' if none is provided)
  *      tp: Set to point to the actual name of the mount point to nuke.
  */
-BOOL RemoveMount(CStringArray& files)
+BOOL
+RemoveMount(CStringArray& files)
 {
     LONG code = 0;
     struct ViceIoctl blob;
@@ -1739,7 +1477,8 @@ BOOL RemoveMount(CStringArray& files)
     return !error;
 }
 
-BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
+BOOL
+GetVolumeInfo(CString strFile, CVolInfo& volInfo)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -1788,7 +1527,8 @@ BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
     return TRUE;
 }
 
-BOOL SetVolInfo(CVolInfo& volInfo)
+BOOL
+SetVolInfo(CVolInfo& volInfo)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -1835,14 +1575,16 @@ BOOL SetVolInfo(CVolInfo& volInfo)
     return TRUE;
 }
 
-void GetCellName(const CString& cellNamep, struct afsconf_cell *infop)
+void
+GetCellName(const CString& cellNamep, struct afsconf_cell *infop)
 {
     CStringUtf8 uCellName(cellNamep);
 
     StringCbCopyA(infop->name, sizeof(infop->name), uCellName);
 }
 
-BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
+BOOL NO_CALLER
+CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
 {
     LONG code;
     struct ViceIoctl blob;
@@ -1909,7 +1651,8 @@ BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bF
     return TRUE;
 }
 
-BOOL GetTokenInfo(CStringArray& tokenInfo)
+BOOL
+GetTokenInfo(CStringArray& tokenInfo)
 {
     int cellNum;
     int rc;
@@ -2012,7 +1755,8 @@ BOOL GetTokenInfo(CStringArray& tokenInfo)
     return TRUE;
 }
 
-UINT MakeSymbolicLink(const CString& strName, const CString& strTarget)
+UINT
+MakeSymbolicLink(const CString& strName, const CString& strTarget)
 {
     struct ViceIoctl blob;
     UINT code;
@@ -2042,7 +1786,8 @@ UINT MakeSymbolicLink(const CString& strName, const CString& strTarget)
     return 0;
 }
 
-void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
+void NO_CALLER
+ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
 {
     ASSERT(nlenPath<MAX_PATH);
     struct ViceIoctl blob;
@@ -2105,7 +1850,8 @@ void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
     strncpy(strPath,space,nlenPath);
 }
 
-BOOL ListSymlink(CStringArray& files)
+BOOL NO_CALLER
+ListSymlink(CStringArray& files)
 {
     LONG code;
     struct ViceIoctl blob;