From 64a65ad7dc896ff39d68a9e622ee457c009ed5d7 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 19 Jun 2004 17:00:13 +0000 Subject: [PATCH] fs-sysname-20040619 Begin the process of supporting multiple sysnames on Windows as is done on Unix. These changes replace the internal variable with a list of sysnames. Still to do: change command line interface to allow entry of multiple names; and replace cm_ExpandSysName() with code similar to Unix which allows expansion of one element in the list at a time. --- src/WINNT/afsd/cm_ioctl.c | 93 ++++++++++++++++++++++++++++++------ src/WINNT/afsd/cm_ioctl.h | 6 +++ src/WINNT/afsd/cm_vnodeops.c | 30 ++++++------ src/WINNT/afsd/fs.c | 44 ++++++++++------- 4 files changed, 126 insertions(+), 47 deletions(-) diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index c2b0c7cf21..cb35ba25b4 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -1079,7 +1079,6 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp) */ cm_cell_t *cp; - cm_cell_t *tcp; cm_SkipIoctlPath(ioctlp); lock_ObtainWrite(&cm_cellLock); @@ -1137,30 +1136,94 @@ long cm_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp) long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long setSysName; - char *cp; + long setSysName, foundname = 0; + char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME]; + int t, count, num = 0; + char **sysnamelist[MAXSYSNAME]; cm_SkipIoctlPath(ioctlp); - memcpy(&setSysName, ioctlp->inDatap, sizeof(long)); - ioctlp->inDatap += sizeof(long); + memcpy(&setSysName, ioctlp->inDatap, sizeof(long)); + ioctlp->inDatap += sizeof(long); - if (setSysName) { - strcpy(cm_sysName, ioctlp->inDatap); + if (setSysName) { + /* check my args */ + if ( setSysName < 0 || setSysName > MAXNUMSYSNAMES ) + return EINVAL; + cp2 = ioctlp->inDatap; + for ( cp=ioctlp->inDatap, count = 0; count < setSysName; count++ ) { + /* won't go past end of ioctlp->inDatap since maxsysname*num < ioctlp->inDatap length */ + t = strlen(cp); + if (t >= MAXSYSNAME || t <= 0) + return EINVAL; + /* check for names that can shoot us in the foot */ + if (*cp == '.' && (cp[1] == 0 || (cp[1] == '.' && cp[2] == 0))) + return EINVAL; + cp += t + 1; } - else { + /* args ok */ + + /* inname gets first entry in case we're being a translator */ + /* (we are never a translator) */ + t = strlen(ioctlp->inDatap); + memcpy(inname, ioctlp->inDatap, t + 1); + ioctlp->inDatap += t + 1; + num = count; + } + + /* Not xlating, so local case */ + if (!cm_sysName) + osi_panic("cm_IoctlSysName: !cm_sysName\n", __FILE__, __LINE__); + + if (!setSysName) { /* user just wants the info */ + strcpy(outname, cm_sysName); + foundname = cm_sysNameCount; + *sysnamelist = cm_sysNameList; + } else { /* Local guy; only root can change sysname */ + /* clear @sys entries from the dnlc, once afs_lookup can + * do lookups of @sys entries and thinks it can trust them */ + /* privs ok, store the entry, ... */ + strcpy(cm_sysName, inname); + if (setSysName > 1) { /* ... or list */ + cp = ioctlp->inDatap; + for (count = 1; count < setSysName; ++count) { + if (!cm_sysNameList[count]) + osi_panic + ("cm_IoctlSysName: no cm_sysNameList entry to write\n" + , __FILE__, __LINE__); + t = strlen(cp); + memcpy(cm_sysNameList[count], cp, t + 1); /* include null */ + cp += t + 1; + } + } + cm_sysNameCount = setSysName; + } + + if (!setSysName) { /* return the sysname to the caller */ - setSysName = 1; /* really means "found sys name */ cp = ioctlp->outDatap; - memcpy(cp, &setSysName, sizeof(long)); - cp += sizeof(long); /* skip found flag */ - strcpy(cp, cm_sysName); - cp += strlen(cp) + 1; /* skip name and terminating null char */ - ioctlp->outDatap = cp; + memcpy(cp, (char *)&foundname, sizeof(afs_int32)); + cp += sizeof(afs_int32); /* skip found flag */ + if (foundname) { + strcpy(cp, outname); + cp += strlen(outname) + 1; /* skip name and terminating null char */ + for ( count=1; count < foundname ; ++count) { /* ... or list */ + if ( !(*sysnamelist)[count] ) + osi_panic("cm_IoctlSysName: no cm_sysNameList entry to read\n" + , __FILE__, __LINE__); + t = strlen((*sysnamelist)[count]); + if (t >= MAXSYSNAME) + osi_panic("cm_IoctlSysName: sysname entry garbled\n" + , __FILE__, __LINE__); + strcpy(cp, (*sysnamelist)[count]); + cp += t + 1; + } } + ioctlp->outDatap = cp; + } /* done: success */ - return 0; + return 0; } long cm_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index 4e9089e2ee..c9ba93249f 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -41,6 +41,12 @@ typedef struct cm_SSetPref { } cm_SSetPref_t; +#define MAXNUMSYSNAMES 16 /* max that current constants allow */ +#define MAXSYSNAME 128 /* max sysname (i.e. @sys) size */ +extern char *cm_sysName; +extern int cm_sysNameCount; +extern char *cm_sysNameList[MAXNUMSYSNAMES]; + #ifndef __CM_IOCTL_INTERFACES_ONLY__ void cm_InitIoctl(void); diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 00b90d3b47..3fc9bbf5d5 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -34,8 +34,6 @@ extern void afsi_log(char *pattern, ...); unsigned int cm_mountRootGen = 0; -char cm_sysName[100]; - /* * Case-folding array. This was constructed by inspecting of SMBtrace output. * I do not know anything more about it. @@ -943,24 +941,24 @@ done: int cm_ExpandSysName(char *inp, char *outp, long outSize) { char *tp; - int prefixCount; - - tp = strrchr(inp, '@'); - if (tp == NULL) return 0; /* no @sys */ - - if (strcmp(tp, "@sys") != 0) return 0; /* no @sys */ - + int prefixCount; + + tp = strrchr(inp, '@'); + if (tp == NULL) return 0; /* no @sys */ + + if (strcmp(tp, "@sys") != 0) return 0; /* no @sys */ + /* caller just wants to know if this is a valid @sys type of name */ if (outp == NULL) return 1; /* otherwise generate the properly expanded @sys name */ - prefixCount = tp - inp; - - strncpy(outp, inp, prefixCount); /* copy out "a." from "a.@sys" */ - outp[prefixCount] = 0; /* null terminate the "a." */ - strcat(outp, cm_sysName); /* append i386_nt40 */ - return 1; -} + prefixCount = tp - inp; + + strncpy(outp, inp, prefixCount); /* copy out "a." from "a.@sys" */ + outp[prefixCount] = 0; /* null terminate the "a." */ + strcat(outp, cm_sysName); /* append i386_nt40 */ + return 1; +} long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp) diff --git a/src/WINNT/afsd/fs.c b/src/WINNT/afsd/fs.c index 560c255923..cae83b6648 100644 --- a/src/WINNT/afsd/fs.c +++ b/src/WINNT/afsd/fs.c @@ -2096,9 +2096,9 @@ static SysNameCmd(as) register struct cmd_syndesc *as; { register afs_int32 code; struct ViceIoctl blob; - register struct cmd_item *ti; + struct cmd_item *ti; char *input = space; - afs_int32 setp = 1; + afs_int32 setp = 0; ti = as->parms[0].items; if (ti) { @@ -2113,39 +2113,51 @@ register struct cmd_syndesc *as; { return EACCES; } #endif /* WIN32 */ - } else { - setp = 0; } + blob.in = space; blob.out = space; blob.out_size = MAXSIZE; blob.in_size = sizeof(afs_int32); memcpy(input, &setp, sizeof(afs_int32)); input += sizeof(afs_int32); - if (ti) { - strcpy(input, ti->data); - blob.in_size += strlen(ti->data) + 1; - input += strlen(ti->data); - *(input++) = '\0'; + for (; ti; ti = ti->next) { + setp++; + blob.in_size += strlen(ti->data) + 1; + if (blob.in_size > MAXSIZE) { + fprintf(stderr, "%s: sysname%s too long.\n", pn, + setp > 1 ? "s" : ""); + return 1; + } + strcpy(input, ti->data); + input += strlen(ti->data); + *(input++) = '\0'; } + memcpy(space, &setp, sizeof(afs_int32)); code = pioctl(0, VIOC_AFS_SYSNAME, &blob, 1); if (code) { - Die(errno, 0); - exit(1); + Die(errno, 0); + return 1; } if (setp) { - printf("%s: new sysname set.\n", pn); + printf("%s: new sysname%s set.\n", pn, setp > 1 ? "s" : ""); + return 0; } - else { + input = space; memcpy(&setp, input, sizeof(afs_int32)); input += sizeof(afs_int32); if (!setp) { fprintf(stderr,"No sysname name value was found\n"); - } else { - printf("Current sysname is '%s'\n", input); + return 1; + } + + printf("Current sysname%s", setp > 1 ? "s are" : " is"); + for (; setp > 0; --setp ) { + printf(" \'%s\'", input); + input += strlen(input) + 1; } - } + printf("\n"); return 0; }