From: Jeff Riegel Date: Fri, 5 Oct 2001 22:40:44 +0000 (+0000) Subject: windows-afsdb-and-freelance-afs-root-support-20011005 X-Git-Tag: openafs-devel-1_3_0~241 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=2d1ee8cf3d0519e584d5f0bf1979b5ec397898ce windows-afsdb-and-freelance-afs-root-support-20011005 afsdb record support for windows freelance /afs (make up an afs root instead of using root.afs from some cell) support for windows --- diff --git a/src/Makefile.djgpp b/src/Makefile.djgpp index e0316f8..23f2dce 100644 --- a/src/Makefile.djgpp +++ b/src/Makefile.djgpp @@ -4,7 +4,10 @@ OBJ = $(SYS_NAME)/obj DEST = $(SYS_NAME)/dest +DESTDIR = DEST/ +SRCDIR = ${DESTDIR} #LINUX_SYS = i386_linux22 +TOP_SRCDIR = `pwd`/src all: afsd diff --git a/src/NTMake9x b/src/NTMake9x index 2e76674..8fb9842 100644 --- a/src/NTMake9x +++ b/src/NTMake9x @@ -179,7 +179,13 @@ sys: cm_headers $(NTMAKE) $(CD) ..\.. -auth: sys +afsdobjs: sys + echo ***** $@ + $(CD) $(OBJ)\WINNT\afsd + $(NTMAKE_OBJS) + $(CD) ..\..\.. + +auth: afsdobjs echo ***** $@ $(CD) $(OBJ)\$@ $(NTMAKE) diff --git a/src/NTMakefile b/src/NTMakefile index 268119a..07cc29a 100644 --- a/src/NTMakefile +++ b/src/NTMakefile @@ -21,6 +21,7 @@ CD = cd NTMAKE = nmake /nologo /f ntmakefile install NTMAKELANG = nmake /nologo /f ntmakefile en_US NTMAKE_HEADERS = nmake /nologo /f ntmakefile install_headers +NTMAKE_OBJS = nmake /nologo /f ntmakefile install_objs MKDIR = mkdir OBJ = src @@ -178,7 +179,13 @@ sys: cm_headers $(NTMAKE) $(CD) ..\.. -auth: sys +afsdobjs: sys + echo ***** $@ + $(CD) $(OBJ)\WINNT\afsd + $(NTMAKE_OBJS) + $(CD) ..\..\.. + +auth: afsdobjs echo ***** $@ $(CD) $(OBJ)\$@ $(NTMAKE) diff --git a/src/WINNT/afsd/Makefile.djgpp b/src/WINNT/afsd/Makefile.djgpp index 6788573..8848874 100644 --- a/src/WINNT/afsd/Makefile.djgpp +++ b/src/WINNT/afsd/Makefile.djgpp @@ -9,7 +9,8 @@ SOURCES = afsd95.c afsd_init95.c cm_access.c cm_aclent.c cm_buf.c \ cm_dcache.c cm_dir.c cm_dnlc.c cm_ioctl.c cm_scache.c \ cm_server.c cm_user.c cm_utils.c cm_vnodeops.c cm_volume.c \ dosutils95.c largeint95.c netbios95.c smb.c smb_ioctl.c \ - cm_diskcache95.c queue95.c afsmsg95.c smb3.c + cm_diskcache95.c queue95.c afsmsg95.c smb3.c cm_dns.c \ + cm_freelance.c include ../../config/Makefile.djgpp.common @@ -24,7 +25,7 @@ all : $(TARGETS) install : $(DESTBIN)/afsd.exe #$(DESTBIN)/klog.exe #CFLAGS += -I../vxd_lib #CFLAGS += -DAFS_VXD -CFLAGS += -DDOS_PKT_WHOLE +CFLAGS += -DDOS_PKT_WHOLE -DAFS_AFSDB_ENV -DAFS_FREELANCE_CLIENT INCFILES = \ $(DESTINC)/netbios95.h \ diff --git a/src/WINNT/afsd/NTMakefile b/src/WINNT/afsd/NTMakefile index e8e33da..4e5af5a 100644 --- a/src/WINNT/afsd/NTMakefile +++ b/src/WINNT/afsd/NTMakefile @@ -36,12 +36,15 @@ INCFILES =\ $(INCFILEDIR)\smb_iocons.h \ $(INCFILEDIR)\smb_ioctl.h \ $(INCFILEDIR)\afsmsg95.h \ - $(INCFILEDIR)\afsrpc.h + $(INCFILEDIR)\afsrpc.h \ + $(INCFILEDIR)\cm_dns.h \ + $(INCFILEDIR)\cm_dns_private.h IDLFILES =\ afsrpc.h afsrpc_c.obj -CONFOBJS=cm_config.obj +CONFOBJS=cm_config.obj \ + cm_dns.obj AFSDOBJS=\ afsd_init.obj \ @@ -66,7 +69,8 @@ AFSDOBJS=\ cm_aclent.obj \ cm_dnlc.obj \ cm_rpc.obj \ - afsrpc_s.obj + afsrpc_s.obj \ + cm_freelance.obj cm_conn.obj: cm_conn.c $(C2OBJ) -DAFS_PTHREAD_ENV $** @@ -153,6 +157,10 @@ $(LOG95_DLLFILE): $(LOG95_DLLOBJS) ############################################################################ # Install target; primary makefile target +install_objs: cm_dns.obj cm_config.obj + $(COPY) cm_dns.obj $(DESTDIR)\lib + $(COPY) cm_config.obj $(DESTDIR)\lib + install_headers: $(IDLFILES) $(INCFILES) install: install_headers $(CONF_DLLFILE) \ diff --git a/src/WINNT/afsd/afsd.h b/src/WINNT/afsd/afsd.h index 0c6f59f..6456c71 100644 --- a/src/WINNT/afsd/afsd.h +++ b/src/WINNT/afsd/afsd.h @@ -35,7 +35,7 @@ BOOL APIENTRY About(HWND, unsigned int, unsigned int, long); #include "krb.h" #include "krb_prot.h" -#include +/*#include */ #include #include @@ -60,6 +60,7 @@ BOOL APIENTRY About(HWND, unsigned int, unsigned int, long); #include "cm_ioctl.h" #include "cm_dnlc.h" #include "cm_buf.h" +#include "cm_freelance.h" #ifdef DJGPP #include "afs/afsmsg95.h" #endif @@ -96,4 +97,30 @@ extern BOOL isGateway; extern BOOL reportSessionStartups; +#ifdef AFS_FREELANCE_CLIENT + +// yj: Variables used by Freelance Client +extern char *cm_FakeRootDir; // the fake root.afs directory + +extern int cm_noLocalMountPoints; // no. of fake mountpoints + +extern cm_localMountPoint_t* cm_localMountPoints; // array of fake mountpoints + +extern int cm_fakeDirSize; // size (in bytes) of fake root.afs directory + +extern int cm_fakeDirCallback; // state of the fake root.afs directory. indicates + // if it needs to be refreshed + +extern int cm_fakeGettingCallback; // 1 if currently updating the fake root.afs directory, + // 0 otherwise + +extern int cm_fakeDirVersion; // the version number of the root.afs directory. used + // invalidate all the buffers containing root.afs data + // after reinitialization +// ------------------------------------------ +#endif /* AFS_FREELANCE_CLIENT */ + +extern int cm_dnsEnabled; +extern int cm_freelanceEnabled; + #endif /* AFSD_H_ENV */ diff --git a/src/WINNT/afsd/afsd95.c b/src/WINNT/afsd/afsd95.c index 3aa6bc7..75cd53a 100644 --- a/src/WINNT/afsd/afsd95.c +++ b/src/WINNT/afsd/afsd95.c @@ -95,6 +95,8 @@ int main(int argc, char *argv[]) cmd_AddParm(ts, "-tracebuf", CMD_SINGLE, CMD_OPTIONAL, "trace buffer size"); cmd_AddParm(ts, "-startup", CMD_FLAG, CMD_OPTIONAL, "start AFS client"); cmd_AddParm(ts, "-diskcache", CMD_SINGLE, CMD_OPTIONAL, "diskcache size"); + cmd_AddParm(ts, "-afsdb", CMD_FLAG, CMD_OPTIONAL, "use DNS for cell server resolution"); + cmd_AddParm(ts, "-freelance", CMD_FLAG, CMD_OPTIONAL, "virtual AFS root"); return (cmd_Dispatch(argc, argv)); } diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 48cecb4..a09e4c1 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -48,6 +48,9 @@ char cm_mountRoot[1024]; DWORD cm_mountRootLen; int cm_logChunkSize; int cm_chunkSize; +#ifdef AFS_FREELANCE_CLIENT +char *cm_FakeRootDir; +#endif /* freelance */ int smb_UseV3; @@ -82,6 +85,16 @@ cm_initparams_v1 cm_initParams; HANDLE afsi_file; +#ifdef AFS_AFSDB_ENV +int cm_dnsEnabled = 1; +#endif + +/*#ifdef AFS_FREELANCE_CLIENT +extern int cm_freelanceEnabled; +#endif*/ + +void cm_InitFakeRootDir(); + void afsi_start() { @@ -167,6 +180,7 @@ int afsd_InitCM(char **reasonP) HKEY parmKey; DWORD dummyLen; long code; + /*int freelanceEnabled;*/ WSADATA WSAjunk; WSAStartup(0x0101, &WSAjunk); @@ -392,6 +406,32 @@ int afsd_InitCM(char **reasonP) afsi_log("Default SecurityLevel is clear"); } +#ifdef AFS_AFSDB_ENV + dummyLen = sizeof(cm_dnsEnabled); + code = RegQueryValueEx(parmKey, "UseDNS", NULL, NULL, + (BYTE *) &cm_dnsEnabled, &dummyLen); + if (code == ERROR_SUCCESS) { + afsi_log("DNS %s be used to find AFS cell servers", + cm_dnsEnabled ? "will" : "will not"); + } + else { + cm_dnsEnabled = 1; /* default on */ + } +#endif /* AFS_AFSDB_ENV */ + +#ifdef AFS_FREELANCE_CLIENT + dummyLen = sizeof(cm_freelanceEnabled); + code = RegQueryValueEx(parmKey, "FreelanceClient", NULL, NULL, + (BYTE *) &cm_freelanceEnabled, &dummyLen); + if (code == ERROR_SUCCESS) { + afsi_log("Freelance client feature %s activated", + cm_freelanceEnabled ? "is" : "is not"); + } + else { + cm_freelanceEnabled = 0; /* default off */ + } +#endif /* AFS_FREELANCE_CLIENT */ + RegCloseKey (parmKey); /* setup early variables */ @@ -497,20 +537,35 @@ int afsd_InitCM(char **reasonP) return -1; } +#ifdef AFS_AFSDB_ENV + if (cm_InitDNS(cm_dnsEnabled) == -1) + cm_dnsEnabled = 0; /* init failed, so deactivate */ + afsi_log("cm_InitDNS %d", cm_dnsEnabled); +#endif + code = cm_GetRootCellName(rootCellName); afsi_log("cm_GetRootCellName code %d rcn %s", code, (code ? "" : rootCellName)); - if (code != 0) { - *reasonP = "can't find root cell name in afsd.ini"; - return -1; + if (code != 0 && !cm_freelanceEnabled) { + *reasonP = "can't find root cell name in afsd.ini"; + return -1; + } + else if (cm_freelanceEnabled) + cm_rootCellp = NULL; + + if (code == 0 && !cm_freelanceEnabled) { + cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE); + afsi_log("cm_GetCell addr %x", cm_rootCellp); + if (cm_rootCellp == NULL) { + *reasonP = "can't find root cell in afsdcell.ini"; + return -1; + } } - cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE); - afsi_log("cm_GetCell addr %x", cm_rootCellp); - if (cm_rootCellp == NULL) { - *reasonP = "can't find root cell in afsdcell.ini"; - return -1; - } +#ifdef AFS_FREELANCE_CLIENT + if (cm_freelanceEnabled) + cm_InitFreelance(); +#endif return 0; } @@ -524,19 +579,26 @@ int afsd_InitDaemons(char **reasonP) /* this should really be in an init daemon from here on down */ - code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp, &req, CM_FLAG_CREATE, &cm_rootVolumep); - afsi_log("cm_GetVolumeByName code %x root vol %x", code, - (code ? 0xffffffff : cm_rootVolumep)); - if (code != 0) { - *reasonP = "can't find root volume in root cell"; - return -1; + if (!cm_freelanceEnabled) { + code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp, + &req, CM_FLAG_CREATE, &cm_rootVolumep); + afsi_log("cm_GetVolumeByName code %x root vol %x", code, + (code ? 0xffffffff : cm_rootVolumep)); + if (code != 0) { + *reasonP = "can't find root volume in root cell"; + return -1; + } } - /* compute the root fid */ - cm_rootFid.cell = cm_rootCellp->cellID; - cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep); - cm_rootFid.vnode = 1; - cm_rootFid.unique = 1; + /* compute the root fid */ + if (!cm_freelanceEnabled) { + cm_rootFid.cell = cm_rootCellp->cellID; + cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep); + cm_rootFid.vnode = 1; + cm_rootFid.unique = 1; + } + else + cm_FakeRootFid(&cm_rootFid); code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req); afsi_log("cm_GetSCache code %x scache %x", code, @@ -575,3 +637,4 @@ int afsd_InitSMB(char **reasonP, void *aMBfunc) return 0; } + diff --git a/src/WINNT/afsd/afsd_init95.c b/src/WINNT/afsd/afsd_init95.c index 602255f..cdd9ffe 100644 --- a/src/WINNT/afsd/afsd_init95.c +++ b/src/WINNT/afsd/afsd_init95.c @@ -47,6 +47,14 @@ int cm_chunkSize; int afs_diskCacheChunks; char cm_cachePath[128]; int cm_diskCacheEnabled = 0; +#ifdef AFS_AFSDB_ENV +extern int cm_dnsEnabled; +#endif + +#ifdef AFS_FREELANCE_CLIENT +extern int cm_freelanceEnabled; +char *cm_FakeRootDir; +#endif /* freelance */ int smb_UseV3; @@ -84,6 +92,7 @@ BOOL reportSessionStartups = FALSE; int afsd_debug; cm_initparams_v1 cm_initParams; + /* * AFSD Initialization Log * @@ -555,6 +564,16 @@ int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock) afsi_log("Default disk cache size %d", diskCacheSize); } + if (as->parms[22].items) { + /* -noafsdb */ + cm_dnsEnabled = 0; + } + + if (as->parms[23].items) { + /* -freelance */ + cm_freelanceEnabled = 1; + } + if (ParseCacheInfoFile()) { exit(1); } @@ -638,6 +657,13 @@ int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock) rx_StartServer(0); afsi_log("rx_StartServer"); +#ifdef AFS_AFSDB_ENV + /* initialize dns lookup */ + if (cm_InitDNS(cm_dnsEnabled) == -1) + cm_dnsEnabled = 0; /* init failed, so deactivate */ + afsi_log("cm_InitDNS %d", cm_dnsEnabled); +#endif + /* init user daemon, and other packages */ cm_InitUser(); @@ -670,18 +696,27 @@ int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock) code = cm_GetRootCellName(rootCellName); afsi_log("cm_GetRootCellName code %d rcn %s", code, (code ? "" : rootCellName)); - if (code != 0) { + if (code != 0 && !cm_freelanceEnabled) { *reasonP = "can't find root cell name in ThisCell"; return -1; } - - cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE); - afsi_log("cm_GetCell addr %x", cm_rootCellp); - if (cm_rootCellp == NULL) { - *reasonP = "can't find root cell in CellServDB"; - return -1; + else if (cm_freelanceEnabled) + cm_rootCellp = NULL; + + if (code == 0 && !cm_freelanceEnabled) { + cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE); + afsi_log("cm_GetCell addr %x", cm_rootCellp); + if (cm_rootCellp == NULL) { + *reasonP = "can't find root cell in CellServDB"; + return -1; + } } +#ifdef AFS_FREELANCE_CLIENT + if (cm_freelanceEnabled) + cm_InitFreelance(); +#endif + return 0; } @@ -694,19 +729,25 @@ int afsd_InitDaemons(char **reasonP) /* this should really be in an init daemon from here on down */ - code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp, &req, CM_FLAG_CREATE, &cm_rootVolumep); - afsi_log("cm_GetVolumeByName code %x root vol %x", code, - (code ? 0xffffffff : cm_rootVolumep)); - if (code != 0) { - *reasonP = "can't find root volume in root cell"; - return -1; - } + if (!cm_freelanceEnabled) { + code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp, &req, CM_FLAG_CREATE, &cm_rootVolumep); + afsi_log("cm_GetVolumeByName code %x root vol %x", code, + (code ? 0xffffffff : cm_rootVolumep)); + if (code != 0) { + *reasonP = "can't find root volume in root cell"; + return -1; + } + } /* compute the root fid */ - cm_rootFid.cell = cm_rootCellp->cellID; - cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep); - cm_rootFid.vnode = 1; - cm_rootFid.unique = 1; + if (!cm_freelanceEnabled) { + cm_rootFid.cell = cm_rootCellp->cellID; + cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep); + cm_rootFid.vnode = 1; + cm_rootFid.unique = 1; + } + else + cm_FakeRootFid(&cm_rootFid); code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req); afsi_log("cm_GetSCache code %x scache %x", code, @@ -744,3 +785,4 @@ int afsd_InitSMB(char **reasonP) return 0; } + diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index f00938a..959b35a 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -28,6 +28,16 @@ /* read/write lock for all global storage in this module */ osi_rwlock_t cm_callbackLock; +/* +#ifdef AFS_FREELANCE_CLIENT +extern int cm_fakeDirCallback; +extern int cm_fakeGettingCallback; +#endif +*/ +#ifdef AFS_FREELANCE_CLIENT +extern osi_mutex_t cm_Freelance_Lock; +#endif + /* count of # of callback breaking messages received by this CM so far. We use * this count in determining whether there have been any callback breaks that * apply to a call that returned a new callback. If the counter doesn't @@ -568,9 +578,50 @@ void cm_InitCallback(void) */ int cm_HaveCallback(cm_scache_t *scp) { - if (scp->cbServerp != NULL) - return 1; - else return 0; +#ifdef AFS_FREELANCE_CLIENT + // yj: we handle callbacks specially for callbacks on the root directory + // Since it's local, we almost always say that we have callback on it + // The only time we send back a 0 is if we're need to initialize or + // reinitialize the fake directory + + // There are 2 state variables cm_fakeGettingCallback and cm_fakeDirCallback + // cm_fakeGettingCallback is 1 if we're in the process of initialization and + // hence should return false. it's 0 otherwise + // cm_fakeDirCallback is 0 if we haven't loaded the fake directory, it's 1 + // if the fake directory is loaded and this is the first time cm_HaveCallback + // is called since then. We return false in this case to allow cm_GetCallback + // to be called because cm_GetCallback has some initialization work to do. + // If cm_fakeDirCallback is 2, then it means that the fake directory is in + // good shape and we simply return true, provided no change is detected. + int fdc, fgc; + + if (cm_freelanceEnabled && scp->fid.cell==0x1 && scp->fid.volume==0x20000001) { // if it's something on /afs + if (!(scp->fid.vnode==0x1 && scp->fid.unique==0x1)) // if it's not root.afs + return 1; + else { + lock_ObtainMutex(&cm_Freelance_Lock); + fdc = cm_fakeDirCallback; + fgc = cm_fakeGettingCallback; + lock_ReleaseMutex(&cm_Freelance_Lock); + + if (fdc==1) { // first call since init + return 0; + } else if (fdc==2 && !fgc) { // we're in good shape + if (cm_getLocalMountPointChange()) { // check for changes + cm_clearLocalMountPointChange(); // clear the changefile + cm_reInitLocalMountPoints(); // start reinit + return 0; + } + return 1; // no change + } + return 0; + } + } +#endif + + if (scp->cbServerp != NULL) + return 1; + else return 0; } /* need to detect a broken callback that races with our obtaining a callback. @@ -694,6 +745,43 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, int mustCall; long sflags; +#ifdef AFS_FREELANCE_CLIENT + // yj + // The case where a callback is needed on /afs is handled + // specially. We need to fetch the status by calling + // cm_MergeStatus and mark that cm_fakeDirCallback is 2 + if (cm_freelanceEnabled && + scp->fid.cell==0x1 && + scp->fid.volume==0x20000001 && + scp->fid.unique==0x1 && + scp->fid.vnode==0x1) { + // Start by indicating that we're in the process + // of fetching the callback + + lock_ObtainMutex(&cm_Freelance_Lock); + cm_fakeGettingCallback = 1; + lock_ReleaseMutex(&cm_Freelance_Lock); + + // Fetch the status info + cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0); + + // Indicate that the callback is not done + lock_ObtainMutex(&cm_Freelance_Lock); + cm_fakeDirCallback = 2; + // Indicate that we're no longer fetching the callback + cm_fakeGettingCallback = 0; + lock_ReleaseMutex(&cm_Freelance_Lock); + + return 0; + } + + /*if (scp->fid.cell==0x1 && scp->fid.volume==0x20000001) { + afsi_log("cm_getcallback should NEVER EVER get here... "); + }*/ + // yj: end of getcallback modifications --------------- + +#endif /* AFS_FREELANCE_CLIENT */ + mustCall = (flags & 1); cm_AFSFidFromFid(&tfid, &scp->fid); while (1) { diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index b8317eb..5ef16bc 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -60,20 +60,38 @@ cm_cell_t *cm_GetCell(char *namep, long flags) cm_cell_t *cp; long code; static cellCounter = 1; /* locked by cm_cellLock */ + int ttl; lock_ObtainWrite(&cm_cellLock); for(cp = cm_allCellsp; cp; cp=cp->nextp) { if (strcmp(namep, cp->namep) == 0) break; } - if (!cp && (flags & CM_FLAG_CREATE)) { - cp = malloc(sizeof(*cp)); + + if ((!cp && (flags & CM_FLAG_CREATE)) +#ifdef AFS_AFSDB_ENV + /* if it's from DNS, see if it has expired */ + || (cp && (cp->flags & CM_CELLFLAG_DNS) && (time(0) > cp->timeout)) +#endif + ) { + if (!cp) cp = malloc(sizeof(*cp)); memset(cp, 0, sizeof(*cp)); code = cm_SearchCellFile(namep, NULL, cm_AddCellProc, cp); - if (code) { - free(cp); - cp = NULL; - goto done; - } +#ifdef AFS_AFSDB_ENV + if (code && cm_dnsEnabled) { + code = cm_SearchCellByDNS(namep, NULL, &ttl, cm_AddCellProc, cp); +#endif + if (code) { + free(cp); + cp = NULL; + goto done; + } +#ifdef AFS_AFSDB_ENV + else { /* got cell from DNS */ + cp->flags |= CM_CELLFLAG_DNS; + cp->timeout = time(0) + ttl; + } + } +#endif /* randomise among those vlservers having the same rank*/ cm_RandomizeServer(&cp->vlServersp); @@ -100,11 +118,30 @@ done: cm_cell_t *cm_FindCellByID(long cellID) { cm_cell_t *cp; + int ttl; + int code; lock_ObtainWrite(&cm_cellLock); for(cp = cm_allCellsp; cp; cp=cp->nextp) { if (cellID == cp->cellID) break; } + +#ifdef AFS_AFSDB_ENV + /* if it's from DNS, see if it has expired */ + if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) && (time(0) > cp->timeout)) { + code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp); + if (code == 0) { /* got cell from DNS */ + cp->flags |= CM_CELLFLAG_DNS; +#ifdef DEBUG + fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl); +#endif + cp->timeout = time(0) + ttl; + } + /* if we fail to find it this time, we'll just do nothing and leave the + current entry alone */ + } +#endif /* AFS_AFSDB_ENV */ + lock_ReleaseWrite(&cm_cellLock); return cp; diff --git a/src/WINNT/afsd/cm_cell.h b/src/WINNT/afsd/cm_cell.h index ca0ae38..a642d04 100644 --- a/src/WINNT/afsd/cm_cell.h +++ b/src/WINNT/afsd/cm_cell.h @@ -20,9 +20,11 @@ typedef struct cm_cell { struct cm_serverRef *vlServersp; /* locked by cm_serverLock */ osi_mutex_t mx; /* mutex locking fields (flags) */ long flags; /* locked by mx */ + long timeout; /* if dns, time at which the server addrs expire */ } cm_cell_t; #define CM_CELLFLAG_SUID 1 /* setuid flag; not yet used */ +#define CM_CELLFLAG_DNS 2 /* cell servers are from DNS */ extern void cm_InitCell(void); diff --git a/src/WINNT/afsd/cm_config.c b/src/WINNT/afsd/cm_config.c index a3ef82f..10a0d44 100644 --- a/src/WINNT/afsd/cm_config.c +++ b/src/WINNT/afsd/cm_config.c @@ -22,6 +22,10 @@ #include #include "cm_config.h" +#ifdef AFS_AFSDB_ENV +#include "cm_dns.h" +#include +#endif char AFSConfigKeyName[] = "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"; @@ -276,6 +280,35 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep, } /* while loop processing all lines */ } +long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl, + cm_configProc_t *procp, void *rockp) +{ +#ifdef AFS_AFSDB_ENV + int rc; + int cellHosts[AFSMAXCELLHOSTS]; + int numServers; + int i; + struct sockaddr_in vlSockAddr; + + rc = getAFSServer(cellNamep, cellHosts, &numServers, ttl); + if (rc == 0 && numServers > 0) { /* found the cell */ + for (i = 0; i < numServers; i++) { + memcpy(&vlSockAddr.sin_addr.s_addr, &cellHosts[i], + sizeof(long)); + vlSockAddr.sin_family = AF_INET; + /* sin_port supplied by connection code */ + if (procp) + (*procp)(rockp, &vlSockAddr, NULL); + if(newCellNamep) + strcpy(newCellNamep,cellNamep); + } + return 0; /* found cell */ + } + else +#endif /* AFS_AFSDB_ENV */ + return -1; /* not found */ +} + #if !defined(DJGPP) && !defined(AFS_WIN95_ENV) /* look up the root cell's name in the Registry */ long cm_GetRootCellName(char *cellNamep) @@ -553,3 +586,32 @@ extern long cm_CloseCellFile(cm_configFile_t *filep) return code; } + +void cm_GetConfigDir(char *dir) +{ + char wdir[256]; + char *afsconf_path; + int code; + int tlen; + +#if !defined(DJGPP) && !defined(AFS_WIN95_ENV) + code = GetWindowsDirectory(wdir, sizeof(wdir)); + if (code == 0 || code > sizeof(wdir)) wdir[0] = 0; + + /* add trailing backslash, if required */ + tlen = strlen(wdir); + if (wdir[tlen-1] != '\\') strcat(wdir, "\\"); +#else +#ifdef DJGPP + strcpy(wdir,cm_confDir); +#else + afsconf_path = getenv("AFSCONF"); + if (!afsconf_path) + strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH); + else + strcpy(wdir, afsconf_path); +#endif /* !DJGPP */ + strcat(wdir,"\\"); +#endif /* DJGPP || WIN95 */ + strcpy(dir, wdir); +} diff --git a/src/WINNT/afsd/cm_config.h b/src/WINNT/afsd/cm_config.h index 19ab236..11996e5 100644 --- a/src/WINNT/afsd/cm_config.h +++ b/src/WINNT/afsd/cm_config.h @@ -36,6 +36,9 @@ extern long cm_GetRootCellName(char *namep); extern long cm_SearchCellFile(char *cellNamep, char *newCellNamep, cm_configProc_t *procp, void *rockp); +extern long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl, + cm_configProc_t *procp, void *rockp); + extern long cm_WriteConfigString(char *labelp, char *valuep); extern long cm_WriteConfigInt(char *labelp, long value); diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 69a08cd..6a7a3ac 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -23,6 +23,9 @@ #include "afsd.h" osi_mutex_t cm_bufGetMutex; +#ifdef AFS_FREELANCE_CLIENT +extern osi_mutex_t cm_Freelance_Lock; +#endif /* functions called back from the buffer package when reading or writing data, * or when holding or releasing a vnode pointer. @@ -1075,11 +1078,23 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, struct rx_call *callp; cm_bulkIO_t biod; /* bulk IO descriptor */ cm_conn_t *connp; + int getroot; + long t1, t2; /* now, the buffer may or may not be filled with good data (buf_GetNew * drops lots of locks, and may indeed return a properly initialized * buffer, although more likely it will just return a new, empty, buffer. */ + +#ifdef AFS_FREELANCE_CLIENT + + // yj: if they're trying to get the /afs directory, we need to + // handle it differently, since it's local rather than on any + // server + + getroot = (scp==cm_rootSCachep) ; +#endif + cm_AFSFidFromFid(&tfid, &scp->fid); code = cm_SetupFetchBIOD(scp, &bufp->offset, &biod, up, reqp); @@ -1120,6 +1135,73 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, scp->dataVersion, bufp->dataVersion, scp, bufp, bufp->dcp); #endif /* DISKCACHE95 */ +#ifdef AFS_FREELANCE_CLIENT + + // yj code + // if getroot then we don't need to make any calls + // just return fake data + + if (cm_freelanceEnabled && getroot) { + // setup the fake status + afsStatus.InterfaceVersion = 0x1; + afsStatus.FileType = 0x2; + afsStatus.LinkCount = scp->linkCount; + afsStatus.Length = cm_fakeDirSize; + afsStatus.DataVersion = cm_fakeDirVersion; + afsStatus.Author = 0x1; + afsStatus.Owner = 0x0; + afsStatus.CallerAccess = 0x9; + afsStatus.AnonymousAccess = 0x9; + afsStatus.UnixModeBits = 0x1ff; + afsStatus.ParentVnode = 0x1; + afsStatus.ParentUnique = 0x1; + afsStatus.SegSize = 0; + afsStatus.ClientModTime = 0x3b49f6e2; + afsStatus.ServerModTime = 0x3b49f6e2; + afsStatus.Group = 0; + afsStatus.SyncCounter = 0; + afsStatus.dataVersionHigh = 0; + + // once we're done setting up the status info, + // we just fill the buffer pages with fakedata + // from cm_FakeRootDir. Extra pages are set to + // 0. + + lock_ObtainMutex(&cm_Freelance_Lock); +#ifdef DEBUG + afsi_log("bufp->offset is %d", bufp->offset); +#endif + t1 = bufp->offset.LowPart; + qdp = biod.bufListEndp; + while (qdp) { + tbufp = osi_GetQData(qdp); + bufferp=tbufp->datap; + memset(bufferp, 0, buf_bufferSize); + t2 = cm_fakeDirSize - t1; + if (t2>buf_bufferSize) t2=buf_bufferSize; +#ifdef DEBUG + afsi_log("t1:%d, t2:%d", t1, t2); +#endif + if (t2 > 0) { + memcpy(bufferp, cm_FakeRootDir+t1, t2); + } else { + t2 = 0; + } + t1+=t2; + qdp = (osi_queueData_t *) osi_QPrev(&qdp->q); + + } + lock_ReleaseMutex(&cm_Freelance_Lock); + + // once we're done, we skip over the part of the + // code that does the ACTUAL fetching of data for + // real files + + goto fetchingcompleted; + } + +#endif /* AFS_FREELANCE_CLIENT */ + /* now make the call */ do { code = cm_Conn(&scp->fid, up, reqp, &connp); @@ -1230,6 +1312,8 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, osi_Log0(afsd_logp, "CALL FetchData DONE"); } while (cm_Analyze(connp, up, reqp, &scp->fid, &volSync, NULL, code)); + + fetchingcompleted: code = cm_MapRPCError(code, reqp); lock_ObtainMutex(&scp->mx); diff --git a/src/WINNT/afsd/cm_dns.c b/src/WINNT/afsd/cm_dns.c new file mode 100644 index 0000000..b0e1da0 --- /dev/null +++ b/src/WINNT/afsd/cm_dns.c @@ -0,0 +1,687 @@ +/* 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 + */ + +#ifdef AFS_AFSDB_ENV + +#include +#include +#ifndef DJGPP +#include +#include +#endif +#include "cm_dns_private.h" +#include "cm_dns.h" +#include +#include + +extern int errno; +static char dns_addr[30]; +#ifdef DJGPP +extern char cm_confDir[]; +#endif +int cm_dnsEnabled = -1; + +void DNSlowerCase(char *str) +{ + int i; + + for (i=0; i= 'A' && str[i] <= 'Z') + str[i] += 'a' - 'A'; +} + +int cm_InitDNS(int enabled) +{ + char configpath[100]; + int len; + int code; + char *path; + char *addr; + + if (!enabled) { fprintf(stderr, "DNS support disabled\n"); cm_dnsEnabled = 0; return 0; } + + /* First try AFS_NS environment var. */ + addr = getenv("AFS_NS"); + if (addr && inet_addr(addr) != -1) { + strcpy(dns_addr, addr); + } else { + /* Now check for the AFSDNS.INI file */ +#ifdef DJGPP + strcpy(configpath, cm_confDir); +#elif defined(AFS_WIN95_ENV) + path = getenv("AFSCONF"); + if (path) strcpy(configpath, path); + else strcpy(configpath, "c:\\afscli"); +#else /* nt */ + code = GetWindowsDirectory(configpath, sizeof(configpath)); + if (code == 0 || code > sizeof(configpath)) return -1; +#endif + strcat(configpath, "\\afsdns.ini"); + + /* Currently we only get (and query) the first nameserver. Getting + list of mult. nameservers should be easy to do. */ + len = GetPrivateProfileString("AFS Domain Name Servers", "ns1", NULL, + dns_addr, sizeof(dns_addr), + configpath); + + if (len == 0 || inet_addr(dns_addr) == -1) { + fprintf(stderr, "No valid name server addresses found, DNS lookup is " + "disabled\n"); + cm_dnsEnabled = 0; /* failed */ + return -1; /* No name servers defined */ + } + else fprintf(stderr, "Found DNS server %s\n", dns_addr); + } + + cm_dnsEnabled = 1; + return 0; +} + +SOCKADDR_IN setSockAddr(char *server, int port) +{ + SOCKADDR_IN sockAddr; + int addrLen = sizeof(SOCKADDR_IN); + +#ifndef WIN32_LEAN_AND_MEAN + bzero(&sockAddr,addrLen); +#endif /*WIN32_LEAN_AND_MEAN*/ + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons( port ); + sockAddr.sin_addr.s_addr = inet_addr( server ); + /*inet_aton(server, &sockAddr.sin_addr.s_addr);*/ + + return (sockAddr); +} + +int getRRCount(PDNS_HDR ptr) +{ + return(ntohs(ptr->rr_count)); +} + + +int send_DNS_Addr_Query(char* query, + SOCKET commSock, SOCKADDR_IN sockAddr, char *buffer) +{ + PDNS_HDR pDNShdr; + PDNS_QTAIL pDNS_qtail; + + int queryLen = 0; + int res; + +#ifndef WIN32_LEAN_AND_MEAN + bzero(buffer,BUFSIZE); +#endif /*WIN32_LEAN_AND_MEAN*/ + + /********************************* + * Build DNS Query Message * + * * + * hard-coded Adrress (A) query * + *********************************/ + + pDNShdr = (PDNS_HDR)&( buffer[ 0 ] ); + pDNShdr->id = htons( 0xDADE ); + pDNShdr->flags = htons( DNS_FLAG_RD ); /* do recurse */ + pDNShdr->q_count = htons( 1 ); /* one query */ + pDNShdr->rr_count = 0; /* none in query */ + pDNShdr->auth_count = 0; /* none in query */ + pDNShdr->add_count = 0; /* none in query */ + + queryLen = putQName( query, &(buffer[ DNS_HDR_LEN ] ) ); + queryLen += DNS_HDR_LEN; /* query Length is just after the query name and header */ +#ifdef DEBUG + fprintf(stderr, "send_DNS_Addr: query=%s, queryLen=%d\n", query, queryLen); +#endif + + + pDNS_qtail = (PDNS_QTAIL) &(buffer[ queryLen ]); + pDNS_qtail->qtype = htons(255);/*htons(DNS_RRTYPE_A); */ + pDNS_qtail->qclass = htons(DNS_RRCLASS_IN); + queryLen += DNS_QTAIL_LEN; + + /************************** + * Send DNS Query Message * + **************************/ + + + res = sendto( commSock, + buffer, + queryLen, + 0, + (struct sockaddr *) &sockAddr, + sizeof( SOCKADDR_IN ) ); + + /*dumpSbuffer(buffer,queryLen);*/ + + if ( res < 0 ) + { +#ifdef DEBUG + fprintf(stderr, "send_DNS_Addr_Query: error %d, errno %d\n", res, errno); + fprintf(stderr, "sendto() failed \n"); +#endif + return ( -1 ); + } + else + { + /*printf( "sendto() succeeded\n");*/ + ; + } /* end if */ + + return(0); +} + + +int send_DNS_AFSDB_Query(char* query, + SOCKET commSock, SOCKADDR_IN sockAddr, char *buffer) +{ + /*static char buffer[BUFSIZE];*/ + + PDNS_HDR pDNShdr; + PDNS_QTAIL pDNS_qtail; + + int queryLen = 0; + int res; + +#ifndef WIN32_LEAN_AND_MEAN + bzero(buffer,BUFSIZE); +#endif /*WIN32_LEAN_AND_MEAN*/ + + /*************************** + * Build DNS Query Message * + * * + * hard-coded AFSDB query * + ***************************/ + + pDNShdr = (PDNS_HDR)&( buffer[ 0 ] ); + pDNShdr->id = htons( 0xDEAD ); + pDNShdr->flags = htons( DNS_FLAG_RD ); /* do recurse */ + pDNShdr->q_count = htons( 1 ); /* one query */ + pDNShdr->rr_count = 0; /* none in query */ + pDNShdr->auth_count = 0; /* none in query */ + pDNShdr->add_count = 0; /* none in query */ + + queryLen = putQName( query, &(buffer[ DNS_HDR_LEN ] ) ); + queryLen += DNS_HDR_LEN; /* query Length is just after the query name and header */ + + + pDNS_qtail = (PDNS_QTAIL) &(buffer[ queryLen ]); + pDNS_qtail->qtype = htons(DNS_RRTYPE_AFSDB); + pDNS_qtail->qclass = htons(DNS_RRCLASS_IN); + queryLen += DNS_QTAIL_LEN; + + /************************** + * Send DNS Query Message * + **************************/ + + res = sendto( commSock, + buffer, + queryLen, + 0, + (struct sockaddr *) &sockAddr, + sizeof( SOCKADDR_IN ) ); + + /*dumpSbuffer(buffer,queryLen);*/ + + if ( res < 0 ) + { +#ifdef DEBUG + fprintf(stderr, "send_DNS_AFSDB_Query: error %d, errno %d\n", res, errno); + fprintf(stderr, "sendto() failed \n"); +#endif /* DEBUG */ + return ( -1 ); + } + else + { + /*printf( "sendto() succeeded\n");*/ + ; + } /* end if */ + + return(0); +} + + +PDNS_HDR get_DNS_Response(SOCKET commSock, SOCKADDR_IN sockAddr, char *buffer) +{ + /*static char buffer[BUFSIZE];*/ + + int addrLen = sizeof(SOCKADDR_IN); + int res; + int size; + +#ifndef WIN32_LEAN_AND_MEAN + bzero(buffer,BUFSIZE); +#endif /*WIN32_LEAN_AND_MEAN*/ + + /***************************** + * Receive DNS Reply Message * + *****************************/ + + /*printf( "calling recvfrom() on connected UDP socket\n" );*/ + + size = recvfrom( commSock, + buffer, + BUFSIZE, + 0, + (struct sockaddr *) &sockAddr, + &addrLen ); + if (size < 0) { fprintf(stderr, "recvfrom error %d\n", errno); return NULL; } + + /*dumpRbuffer(buffer,res);*/ + +#ifdef DEBUG + fprintf(stderr, "recvfrom returned %d bytes from %s: \n", + size, inet_ntoa( sockAddr.sin_addr ) ); +#endif /* DEBUG */ + + return((PDNS_HDR)&( buffer[ 0 ] )); + +} + + +int putQName( char *pHostName, char *pQName ) +{ + int i; + char c; + int j = 0; + int k = 0; + + DNSlowerCase(pHostName); + /*printf( "Hostname: [%s]\n", pHostName );*/ + + for ( i = 0; *( pHostName + i ); i++ ) + { + c = *( pHostName + i ); /* get next character */ + + + if ( c == '.' ) + { + /* dot encountered, fill in previous length */ + if (k!=0){ /*don't process repeated dots*/ + /*printf( "%c", c );*/ + *( pQName + j ) = k; + j = j+k+1; /* set index to next counter */ + k = 0; /* reset segment length */ + } + } + else + { + /*printf( "%c", c );*/ + *( pQName + j + k + 1 ) = c; /* assign to QName */ + k++; /* inc count of seg chars */ + } /* end if */ + } /* end for loop */ + + *(pQName + j ) = k; /* count for final segment */ + + *(pQName + j + k + 1 ) = 0; /* count for trailing NULL segment is 0 */ + + /*printf( "\n" ); */ + + if (c == '.') + return ( j + k + 1 ); /* return total length of QName */ + else + return ( j + k + 2 ); +} /* end putQName() */ + + +u_char * skipRRQName(u_char *pQName) +{ + u_char *ptr; + u_char c; + + ptr = pQName; + c = *ptr; + while (c) { + if ( c >= 0xC0 ) { + /* skip the 'compression' pointer */ + ptr = ptr+1; + c = '\0'; + } else { + /* skip a normal qname segment */ + ptr += *ptr; + ptr++; + c = *ptr; + }; + }; + + /* ptr now pointing at terminating zero of query QName, + or the pointer for the previous occurrence + (compression) + */ + ptr++; + + return (ptr); +} /* end skipRRQName() */ + + + +u_char * printRRQName( u_char *pQName, PDNS_HDR buffer ) +{ + u_short i, k; + u_char *buffPtr = (u_char *) buffer; + u_char *namePtr; + u_char *retPtr; + u_char c; + + + namePtr = pQName; + retPtr = 0; + + for ( i = 0; i < BUFSIZE; i++ ) + { + c = *namePtr; + if ( c >= 0xC0 ) { + c = *(namePtr + 1); + retPtr = namePtr+2; + namePtr = buffPtr+c; + } else { + if ( c == 0 ) + break; + + for ( k = 1; k <= c; k++ ) + { + fprintf(stderr, "%c", *( namePtr + k ) ); + } /* end for loop */ + fprintf(stderr,"."); + namePtr += k; + } + } /* end for loop */ + fprintf(stderr,"\n"); + namePtr++; /* skip terminating zero */ + + if (retPtr) + return(retPtr); + else + return(namePtr); + +} /* end printRRQName() */ + + +u_char * sPrintRRQName( u_char *pQName, PDNS_HDR buffer, char *str ) +{ + u_short i, k; + u_char *buffPtr = (u_char *) buffer; + u_char *namePtr; + u_char *retPtr; + u_char c; + + char section[64]; + + strcpy(str,""); + namePtr = pQName; + retPtr = 0; + + for ( i = 0; i < BUFSIZE; i++ ) + { + c = *namePtr; + if ( c >= 0xC0 ) { + c = *(namePtr + 1); + retPtr = namePtr+2; + namePtr = buffPtr+c; + } else { + if ( c == 0 ) + break; + + for ( k = 1; k <= c; k++ ) + { + sprintf(section,"%c", *( namePtr + k ) ); + strcat(str,section); + } /* end for loop */ + strcat(str,"."); + namePtr += k; + } + } /* end for loop */ + namePtr++; /* skip terminating zero */ + + if (retPtr) + return(retPtr); + else + return(namePtr); + +} /* end sPrintRRQName() */ + + +void printReplyBuffer_AFSDB(PDNS_HDR replyBuff) +{ + u_char *ptr = (u_char *) replyBuff; + int answerCount = ntohs((replyBuff)->rr_count); + u_char i; + PDNS_AFSDB_RR_HDR + rrPtr; + + ptr += DNS_HDR_LEN; + + /* ptr now pointing at start of QName in query field */ + ptr = skipRRQName(ptr); + + + /* skip the query type and class fields */ + ptr+= DNS_QTAIL_LEN; + + /* ptr should now be at the start of the answer RR sections */ + + fprintf(stderr,"---------------------------------\n"); + for (i=0; irr_afsdb_class) == 1) { + fprintf(stderr,"AFDB class %d -> ",ntohs(rrPtr->rr_afsdb_class)); + ptr = printRRQName(ptr,replyBuff); } + else + ptr = skipRRQName(ptr); + }; + fprintf(stderr,"---------------------------------\n"); + + +}; + +void processReplyBuffer_AFSDB(SOCKET commSock, PDNS_HDR replyBuff, int *cellHosts, int *numServers, int *ttl) + /*PAFS_SRV_LIST (srvList)*/ +{ + u_char *ptr = (u_char *) replyBuff; + int answerCount = ntohs((replyBuff)->rr_count); + u_char i; + PDNS_AFSDB_RR_HDR + rrPtr; + int srvCount = 0; + char hostName[256]; + struct in_addr addr; + int rc; + + ptr += DNS_HDR_LEN; + + /* ptr now pointing at start of QName in query field */ + ptr = skipRRQName(ptr); + + + /* skip the query type and class fields */ + ptr+= DNS_QTAIL_LEN; + + /* ptr should now be at the start of the answer RR sections */ + + answerCount = MIN(answerCount, AFSMAXCELLHOSTS); +#ifdef DEBUG + fprintf(stderr, "processRep_AFSDB: answerCount=%d\n", answerCount); +#endif /* DEBUG */ + + for (i=0; irr_afsdb_class) == 1) && + (srvCount < MAX_AFS_SRVS)) { + /*ptr = sPrintRRQName(ptr,replyBuff,srvList->host[srvList->count]);*/ + ptr = sPrintRRQName(ptr,replyBuff,hostName); + /*ptr = printRRQName(ptr,replyBuff);*/ + *ttl = ntohl(rrPtr->rr_ttl); + +#ifdef DEBUG + fprintf(stderr, "resolving name %s\n", hostName); +#endif + /* resolve name from DNS query */ + rc = DNSgetAddr(commSock, hostName, &addr); + if (rc < 0) + continue; /* skip this entry */ +#ifdef DEBUG + fprintf(stderr, "processRep_AFSDB: resolved name %s to addr %x\n", hostName, addr); +#endif /* DEBUG */ + memcpy(&cellHosts[srvCount], &addr.s_addr, sizeof(addr.s_addr)); + srvCount++; + } + else { + ptr = skipRRQName(ptr); + } + } + + *numServers = srvCount; + +} + + +u_char * processReplyBuffer_Addr(PDNS_HDR replyBuff) +{ + u_char *ptr = (u_char *) replyBuff; + int answerCount = ntohs((replyBuff)->rr_count); + u_char i; + PDNS_A_RR_HDR + rrPtr; + +#ifdef DEBUG + fprintf(stderr, "processReplyBuffer_Addr: answerCount=%d\n", answerCount); +#endif /* DEBUG */ + if (answerCount == 0) return 0; + + ptr += DNS_HDR_LEN; + + /* ptr now pointing at start of QName in query field */ + ptr = skipRRQName(ptr); + + + /* skip the query type and class fields */ + ptr+= DNS_QTAIL_LEN; + + /* ptr should now be at the start of the answer RR sections */ + ptr = skipRRQName(ptr); + rrPtr = (PDNS_A_RR_HDR) ptr; + +#ifdef DEBUG + fprintf(stderr, "type:%d, class:%d, ttl:%d, rdlength:%d\n", + ntohs(rrPtr->rr_type),ntohs(rrPtr->rr_class), + ntohl(rrPtr->rr_ttl),ntohs(rrPtr->rr_rdlength)); + fprintf(stderr, "Count %d\tand Answer %8x\n",answerCount,rrPtr->rr_addr); +#endif /* DEBUG */ + + ptr += DNS_A_RR_HDR_LEN; + + return (ptr); + +}; + +int getAFSServer(char *cellName, int *cellHosts, int *numServers, int *ttl) +{ + /*static AFS_SRV_LIST srvList; + static int ans = 0;*/ + SOCKET commSock; + SOCKADDR_IN sockAddr; + PDNS_HDR pDNShdr; + char buffer[BUFSIZE]; + int rc; + +#ifdef DEBUG + fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled); +#endif + + if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */ + cm_InitDNS(1); /* assume enabled */ + } + if (cm_dnsEnabled == 0) { /* possibly we failed in cm_InitDNS above */ + fprintf(stderr, "DNS initialization failed, disabled\n"); + *numServers = 0; + return -1; + } + + sockAddr = setSockAddr(dns_addr, DNS_PORT); + + commSock = socket( AF_INET, SOCK_DGRAM, 0 ); + if ( commSock < 0 ) + { + /*afsi_log("socket() failed\n");*/ + fprintf(stderr, "getAFSServer: socket() failed, errno=%d\n", errno); + *numServers = 0; + return (-1); + } + +#ifdef DJGPP + /* the win95 sock.vxd will not allow sendto for unbound sockets, + * so just bind to nothing and it works */ + + __djgpp_set_socket_blocking_mode(commSock, 0); + bind(commSock,0,sizeof( SOCKADDR_IN ) ); +#endif /* DJGPP */ + + rc = send_DNS_AFSDB_Query(cellName,commSock,sockAddr, buffer); + if (rc < 0) { + fprintf(stderr,"getAFSServer: send_DNS_AFSDB_Query failed\n"); + *numServers = 0; + return -1; + } + + pDNShdr = get_DNS_Response(commSock,sockAddr, buffer); + + /*printReplyBuffer_AFSDB(pDNShdr);*/ + if (pDNShdr) + processReplyBuffer_AFSDB(commSock, pDNShdr, cellHosts, numServers, ttl); + else + *numServers = 0; + + close(commSock); + if (*numServers == 0) + return(-1); + + else + return 0; +} + +int DNSgetAddr(SOCKET commSock, char *hostName, struct in_addr *iNet) +{ + /* Variables for DNS message parsing and creation */ + PDNS_HDR pDNShdr; + + SOCKADDR_IN sockAddr; + char buffer[BUFSIZE]; + + int i; + u_char *addr; + u_long *aPtr; + int rc; + + /********************** + * Get a DGRAM socket * + **********************/ + + sockAddr = setSockAddr(dns_addr, DNS_PORT); + + rc = send_DNS_Addr_Query(hostName,commSock,sockAddr, buffer); + if (rc < 0) return rc; + pDNShdr = get_DNS_Response(commSock,sockAddr, buffer); + if (pDNShdr == NULL) + return -1; + + addr = processReplyBuffer_Addr(pDNShdr); + if (addr == 0) + return -1; + + aPtr = (u_long *) addr; + + iNet->s_addr = *aPtr; + + return(0); +} + +#endif /* AFS_AFSDB_ENV */ diff --git a/src/WINNT/afsd/cm_dns.h b/src/WINNT/afsd/cm_dns.h new file mode 100644 index 0000000..1e5d28c --- /dev/null +++ b/src/WINNT/afsd/cm_dns.h @@ -0,0 +1,27 @@ +/* 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 + */ + +/* Well-known DNS port is 53 (for both TCP and UDP, + although UDP is typically the only one used) */ + +#define DNS_PORT 53 + +/* this function will continue to return cell server + names for the given cell, ending in null */ +int getAFSServer(char *cellname, int *cellHosts, int *numServers, int *ttl); + +/* a supplement for the DJGPP gethostbyname ... which + never bothers calling a DNS server ... so this function + takes care of that. This should be called when you + failed with gethostbyname (as that WILL check for + dotted decimal, and local hostfile) */ + +struct hostent *DNSgetHostByName(char *hostname); + + + diff --git a/src/WINNT/afsd/cm_dns_private.h b/src/WINNT/afsd/cm_dns_private.h new file mode 100644 index 0000000..1344fe0 --- /dev/null +++ b/src/WINNT/afsd/cm_dns_private.h @@ -0,0 +1,217 @@ +/* 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 __DNS_AFS_private_h_env_ +#define __DNS_AFS_private_h_env_ + +#ifdef DJGPP +#include +#include +#include +#include +/*#else + #include */ +#endif + +#ifdef KERNEL +#define SOCKET struct osi_socket * +#else +#define SOCKET int +#endif + +#define SOCKADDR_IN struct sockaddr_in + +#include +#include + + +#ifdef DJGPP + +char *inet_ntoa(struct in_addr in) +{ + static char out[256]; + char temp[20]; + unsigned long sVal,pVal; + + out[0] = '\0'; + + + pVal = ntohl(in.s_addr); + + sVal = pVal; + sVal >>= 24; + sprintf(out,"%ld",sVal); + + sVal = pVal; + sVal <<= 8; + sVal >>= 24; + sprintf(out,"%s.%ld",out,sVal); + + sVal = pVal; + sVal <<= 16; + sVal >>= 24; + sprintf(out,"%s.%ld",out,sVal); + + sVal = pVal; + sVal <<= 24; + sVal >>= 24; + sprintf(out,"%s.%ld",out,sVal); + + return(&out[0]); +} + +unsigned long inet_addr(const char *cp) +{ + + unsigned long val=0; + unsigned char sVal; + + char cp2[256]; + + char* ptr = cp2; + int i; + int len; + + strcpy(cp2,cp); + + for (i=0; i<=strlen(cp); i++) + { + if (cp2[i] == '.') + { + cp2[i] = '\0'; + sVal = atoi(ptr); + ptr = &cp2[i+1]; + val = val << 8; + val &= 0xffffff00; + val |= sVal; + //printf("%x\t%lx\n",sVal,val); + }; + }; + sVal = atoi(ptr); + val = val << 8; + val &= 0xffffff00; + val |= sVal; + //printf("%x\t%lx\n",sVal,val); + + return htonl(val); +} + +#endif /* DJGPP */ + +#define BUFSIZE 2048 + +/* + * AFS Server List (a list of host names and their count) + */ +#define MAX_AFS_SRVS 20 +typedef struct afs_srvlist +{ + unsigned short count; /* number of host names */ + char host[MAX_AFS_SRVS][256];/* array of hosts*/ +} AFS_SRV_LIST, *PAFS_SRV_LIST; + + +/* + * DNS Message Header + */ +typedef struct dns_hdr +{ + unsigned short id; /* client query ID number */ + unsigned short flags; /* qualify contents */ + unsigned short q_count; /* number of questions */ + unsigned short rr_count; /* number of answer RRs */ + unsigned short auth_count; /* number of authority RRs */ + unsigned short add_count; /* number of additional RRs */ +} DNS_HDR, *PDNS_HDR; + +#define DNS_HDR_LEN sizeof(DNS_HDR) + + + +/* THESE WERE ALSO WRONG !!!! */ +#define DNS_FLAG_RD 0x0100 + +/* + * DNS query class and response type for the tail of the query packet + */ +typedef struct dns_qtail +{ + unsigned short qtype; /* Query type (2bytes) - for responses */ + unsigned short qclass; /* Query Class (2bytes) - for questions */ +} DNS_QTAIL, *PDNS_QTAIL; + +#define DNS_QTAIL_LEN sizeof(DNS_QTAIL) + +/* DNS Generic Resource Record format (from RFC 1034 and 1035) + * + * NOTE: The first field in the DNS RR Record header is always + * the domain name in QNAME format (see earlier description) + */ +typedef struct dns_rr_hdr +{ + unsigned short rr_type; /* RR type code (e.g. A, MX, NS, etc.) */ + unsigned short rr_class; /* RR class code (IN for Internet) */ + unsigned long rr_ttl; /* Time-to-live for resource */ + unsigned short rr_rdlength; /* length of RDATA field (in octets) */ +} DNS_RR_HDR, *PDNS_RR_HDR; + +#define DNS_RR_HDR_LEN sizeof(DNS_RR_HDR) + +#define DNS_RRTYPE_A 1 +#define DNS_RRTYPE_NS 2 +#define DNS_RRTYPE_CNAME 5 +#define DNS_RRTYPE_SOA 6 +#define DNS_RRTYPE_WKS 11 +#define DNS_RRTYPE_PTR 12 +#define DNS_RRTYPE_HINFO 13 +#define DNS_RRTYPE_MX 15 +#define DNS_RRTYPE_AFSDB 18 + + +#define DNS_RRCLASS_IN 1 // Internet +#define DNS_RRCLASS_CS 2 // CSNET +#define DNS_RRCLASS_CH 3 // CHAOS Net +#define DNS_RRCLASS_HS 4 // Hesiod +#define DNS_RRCLASS_WILD 255 // WildCard - all classes + +/* + * DNS AFSDB Resource Data Field + */ +typedef struct dns_afsdb_rr_hdr +{ + unsigned short rr_type; /* RR type code (e.g. A, MX, NS, etc.) */ + unsigned short rr_class; /* RR class code (IN for Internet) */ + unsigned long rr_ttl; /* Time-to-live for resource */ + unsigned short rr_rdlength; /* length of RDATA field (in octets) */ + unsigned short rr_afsdb_class; /* 1-AFS , 2-DCE */ +} DNS_AFSDB_RR_HDR, *PDNS_AFSDB_RR_HDR; + +#define DNS_AFSDB_RR_HDR_LEN sizeof(DNS_AFSDB_RR_HDR) + +/* + * DNS A Resource Data Field + */ +typedef struct dns_a_rr_hdr +{ + unsigned short rr_type; /* RR type code (e.g. A, MX, NS, etc.) */ + unsigned short rr_class; /* RR class code (IN for Internet) */ + unsigned long rr_ttl; /* Time-to-live for resource */ + unsigned short rr_rdlength; /* length of RDATA field (in octets) */ + unsigned long rr_addr; /* Resolved host address */ +} DNS_A_RR_HDR, *PDNS_A_RR_HDR; + +#define DNS_A_RR_LEN 14 //sizeof(DNS_A_RR_HDR) +#define DNS_A_RR_HDR_LEN 10 //(DNS_A_RR_LEN - sizeof(unsigned long)) + +int putQName( char *pszHostName, char *pQName ); +unsigned char * printRRQName( unsigned char *pQName, PDNS_HDR buffer ); +unsigned char * skipRRQName(unsigned char *pQName); +/* void printReplyBuffer_AFSDB(PDNS_HDR replyBuff); */ + +#endif //__DNS_AFS_private_h_env_ + diff --git a/src/WINNT/afsd/cm_freelance.c b/src/WINNT/afsd/cm_freelance.c new file mode 100644 index 0000000..6ae0889 --- /dev/null +++ b/src/WINNT/afsd/cm_freelance.c @@ -0,0 +1,525 @@ +#include +#include + +#ifndef DJGPP +#include +#include +#else +#include +#endif /* !DJGPP */ +#include +#include +#include + +#include + +#include "afsd.h" +#ifdef AFS_FREELANCE_CLIENT +#include "cm_freelance.h" +#include "stdio.h" + +int cm_noLocalMountPoints; +int cm_fakeDirSize; +int cm_fakeDirCallback=0; +int cm_fakeGettingCallback=0; +int cm_fakeDirVersion = 0x8; +cm_localMountPoint_t* cm_localMountPoints; +osi_mutex_t cm_Freelance_Lock; +int cm_localMountPointChangeFlag = 0; +int cm_freelanceEnabled = 0; + +void cm_InitFakeRootDir(); + +void cm_InitFreelance() { + + lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock"); + + // yj: first we make a call to cm_initLocalMountPoints + // to read all the local mount points from an ini file + cm_InitLocalMountPoints(); + + // then we make a call to InitFakeRootDir to create + // a fake root directory based on the local mount points + cm_InitFakeRootDir(); + + // --- end of yj code +} + +/* yj: Initialization of the fake root directory */ +/* to be called while holding freelance lock unless during init. */ +void cm_InitFakeRootDir() { + + int i, j, t1, t2; + char* currentPos; + int noChunks; + char mask; + + + // allocate space for the fake info + cm_dirHeader_t fakeDirHeader; + cm_dirEntry_t fakeEntry; + cm_pageHeader_t fakePageHeader; + + // i'm going to calculate how much space is needed for + // this fake root directory. we have these rules: + // 1. there are cm_noLocalMountPoints number of entries + // 2. each page is CM_DIR_PAGESIZE in size + // 3. the first 13 chunks of the first page are used for + // some header stuff + // 4. the first chunk of all subsequent pages are used + // for page header stuff + // 5. a max of CM_DIR_EPP entries are allowed per page + // 6. each entry takes 1 or more chunks, depending on + // the size of the mount point string, as determined + // by cm_NameEntries + // 7. each chunk is CM_DIR_CHUNKSIZE bytes + + int CPP = CM_DIR_PAGESIZE / CM_DIR_CHUNKSIZE; + int curChunk = 13; // chunks 0 - 12 are used for header stuff + // of the first page in the directory + int curPage = 0; + int curDirEntry = 0; + int curDirEntryInPage = 0; + int sizeOfCurEntry; + int dirSize; + + + while (curDirEntry!=cm_noLocalMountPoints) { + sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + if ((curChunk + sizeOfCurEntry >= CPP) || + (curDirEntryInPage + 1 >= CM_DIR_EPP)) { + curPage++; + curDirEntryInPage = 0; + curChunk = 0; + } + curChunk += sizeOfCurEntry; + curDirEntry++; + curDirEntryInPage++; + } + + dirSize = (curPage+1) * CM_DIR_PAGESIZE; + cm_FakeRootDir = malloc(dirSize); + cm_fakeDirSize = dirSize; + + + + // yj: when we get here, we've figured out how much memory we need and + // allocated the appropriate space for it. we now prceed to fill + // it up with entries. + curPage = 0; + curDirEntry = 0; + curDirEntryInPage = 0; + curChunk = 0; + + // fields in the directory entry that are unused. + fakeEntry.flag = 1; + fakeEntry.length = 0; + fakeEntry.next = 0; + fakeEntry.fid.unique = htonl(1); + + // the first page is special, it uses fakeDirHeader instead of fakePageHeader + // we fill up the page with dirEntries that belong there and we make changes + // to the fakeDirHeader.header.freeBitmap along the way. Then when we're done + // filling up the dirEntries in this page, we copy the fakeDirHeader into + // the top of the page. + + // init the freeBitmap array + for (i=0; i<8; i++) + fakeDirHeader.header.freeBitmap[i]=0; + + fakeDirHeader.header.freeBitmap[0] = 0xff; + fakeDirHeader.header.freeBitmap[1] = 0x7f; + + + // we start counting at 13 because the 0th to 12th chunks are used for header + curChunk = 13; + + // stick the first 2 entries "." and ".." in + fakeEntry.fid.unique = htonl(1); + fakeEntry.fid.vnode = htonl(1); + strcpy(fakeEntry.name, "."); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + curChunk++; curDirEntryInPage++; + strcpy(fakeEntry.name, ".."); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + curChunk++; curDirEntryInPage++; + + // keep putting stuff into page 0 if + // 1. we're not done with all entries + // 2. we have less than CM_DIR_EPP entries in page 0 + // 3. we're not out of chunks in page 0 + + while( (curDirEntry!=cm_noLocalMountPoints) && + (curDirEntryInPage < CM_DIR_EPP) && + (curChunk + cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0) <= CPP)) + { + + noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + fakeEntry.fid.vnode = htonl(curDirEntry + 2); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); + curDirEntry++; + curDirEntryInPage++; + for (i=0; inamep, 0) <= CPP)) + { + // add an entry to this page + + noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + fakeEntry.fid.vnode=htonl(curDirEntry+2); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); + curDirEntry++; + curDirEntryInPage++; + for (i=0; icell = 0x1; /* root cell */ + fidp->volume = 0x20000001; /* root.afs ? */ + fidp->vnode = 0x1; + fidp->unique = 0x1; +} + +int cm_getLocalMountPointChange() { + return cm_localMountPointChangeFlag; +} + +int cm_clearLocalMountPointChange() { + cm_localMountPointChangeFlag = 0; +} + +/* called directly from ioctl */ +/* called while not holding freelance lock */ +int cm_noteLocalMountPointChange() { + lock_ObtainMutex(&cm_Freelance_Lock); + cm_fakeDirVersion++; + cm_localMountPointChangeFlag = 1; + lock_ReleaseMutex(&cm_Freelance_Lock); + return 1; +} + +int cm_reInitLocalMountPoints() { + cm_fid_t aFid; + int i, j, hash; + cm_scache_t *scp, **lscpp, *tscp; + + + printf("\n\n----- reinitialization starts ----- \n"); + + + // first we invalidate all the SCPs that were created + // for the local mount points + + printf("Invalidating local mount point scp... "); + + aFid.cell = 0x1; + aFid.volume=0x20000001; + aFid.unique=0x1; + aFid.vnode=0x2; + + lock_ObtainWrite(&cm_scacheLock); + lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */ + for (i=0; inextp) { + if (scp->fid.volume == aFid.volume && + scp->fid.vnode == aFid.vnode && + scp->fid.unique == aFid.unique + ) { + + // mark the scp to be reused + lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainMutex(&scp->mx); + cm_DiscardSCache(scp); + lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; + + // take the scp out of the hash + lscpp = &cm_hashTablep[hash]; + for (tscp=*lscpp; tscp; lscpp = &tscp->nextp, tscp = *lscpp) { + if (tscp == scp) break; + } + *lscpp = scp->nextp; + scp->flags &= ~CM_SCACHEFLAG_INHASH; + + + } + } + aFid.vnode = aFid.vnode + 1; + } + lock_ReleaseWrite(&cm_scacheLock); + printf("\tall old scp cleared!\n"); + + // we must free the memory that was allocated in the prev + // cm_InitLocalMountPoints call + printf("Removing old localmountpoints... "); + free(cm_localMountPoints); + printf("\tall old localmountpoints cleared!\n"); + + // now re-init the localmountpoints + printf("Creating new localmountpoints... "); + cm_InitLocalMountPoints(); + printf("\tcreated new set of localmountpoints!\n"); + + + // now we have to free the memory allocated in cm_initfakerootdir + printf("Removing old fakedir... "); + free(cm_FakeRootDir); + printf("\t\told fakedir removed!\n"); + + // then we re-create that dir + printf("Creating new fakedir... "); + cm_InitFakeRootDir(); + printf("\t\tcreated new fakedir!\n"); + + lock_ReleaseMutex(&cm_Freelance_Lock); + + printf("----- reinit complete -----\n\n"); +} + + +// yj: open up the ini file and read all the local mount +// points that are stored there. Part of the initialization +// process for the freelance client. +/* to be called while holding freelance lock unless during init. */ +long cm_InitLocalMountPoints() { + + FILE *fp; + char line[200]; + int n, i; + char* t; + cm_localMountPoint_t* aLocalMountPoint; + char hdir[120]; + + cm_GetConfigDir(hdir); + strcat(hdir, AFS_FREELANCE_INI); + // open the ini file for reading + fp = fopen(hdir, "r"); + + // if we fail to open the file, create an empty one + if (!fp) { + fp = fopen(hdir, "w"); + fputs("0\n", fp); + fclose(fp); + return 0; /* success */ + } + + // we successfully opened the file +#ifdef DEBUG + fprintf(stderr, "opened afs_freelance.ini\n"); +#endif + + // now we read the first line to see how many entries + // there are + fgets(line, 200, fp); + + // if the line is empty at any point when we're reading + // we're screwed. report error and return. + if (*line==0) { + afsi_log("error occurred while reading afs_freelance.ini"); + fprintf(stderr, "error occurred while reading afs_freelance.ini"); + return -1; + } + + // get the number of entries there are from the first line + // that we read + cm_noLocalMountPoints = atoi(line); + + // create space to store the local mount points + cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints); + aLocalMountPoint = cm_localMountPoints; + + // now we read n lines and parse them into local mount points + // where n is the number of local mount points there are, as + // determined above. + // Each line in the ini file represents 1 local mount point and + // is in the format xxx#yyy:zzz, where xxx is the directory + // entry name, yyy is the cell name and zzz is the volume name. + // #yyy:zzz together make up the mount point. + for (i=0; inamep=malloc(t-line+1); + memcpy(aLocalMountPoint->namep, line, t-line); + *(aLocalMountPoint->namep + (t-line)) = 0; + aLocalMountPoint->mountPointStringp=malloc(strlen(line) - (t-line) + 1); + memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2); + *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0; +#ifdef DEBUG + fprintf(stderr, "found mount point: name %s, string %s\n", + aLocalMountPoint->namep, + aLocalMountPoint->mountPointStringp); +#endif + + aLocalMountPoint++; + + } + fclose(fp); + return 0; +} + + +int cm_getNoLocalMountPoints() { + return cm_noLocalMountPoints; +} + +cm_localMountPoint_t* cm_getLocalMountPoint(int vnode) { + return 0; +} + +long cm_FreelanceAddMount(char *filename, char *cellname, char *volume) +{ + FILE *fp; + char hfile[120]; + char line[200]; + int n; + + lock_ObtainMutex(&cm_Freelance_Lock); + + cm_GetConfigDir(hfile); + strcat(hfile, AFS_FREELANCE_INI); + fp = fopen(hfile, "r+"); + if (!fp) + return CM_ERROR_INVAL; + fgets(line, 200, fp); + n = atoi(line); + n++; + fseek(fp, 0, SEEK_SET); + fprintf(fp, "%d", n); + fseek(fp, 0, SEEK_END); + fprintf(fp, "%s#%s:%s\n", filename, cellname, volume); + fclose(fp); + lock_ReleaseMutex(&cm_Freelance_Lock); + + cm_noteLocalMountPointChange(); + + return 0; +} + +long cm_FreelanceRemoveMount(char *toremove) +{ + int i, n, t1, t2; + char* cp; + char line[200]; + char shortname[200]; + char hfile[120], hfile2[120]; + FILE *fp1, *fp2; + char cmd[200]; + int found=0; + + lock_ObtainMutex(&cm_Freelance_Lock); + + cm_GetConfigDir(hfile); + strcat(hfile, AFS_FREELANCE_INI); + strcpy(hfile2, hfile); + strcat(hfile2, "2"); + fp1=fopen(hfile, "r+"); + if (!fp1) + return CM_ERROR_INVAL; + fp2=fopen(hfile2, "w+"); + if (!fp2) { + fclose(fp1); + return CM_ERROR_INVAL; + } + + fgets(line, 200, fp1); + n=atoi(line); + fprintf(fp2, "%d\n", n-1); + + for (i=0; iinDatap, fullCell, volume); @@ -1164,6 +1172,14 @@ long cm_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp) strcpy(mpInfo, ioctlp->inDatap); } +#ifdef AFS_FREELANCE_CLIENT + if (cm_freelanceEnabled && dscp == cm_rootSCachep) { + /* we are adding the mount point to the root dir., so call + the freelance code to do the add. */ + code = cm_FreelanceAddMount(leaf, fullCell, volume); + return code; + } +#endif /* create the symlink with mode 644. The lack of X bits tells * us that it is a mount point. */ @@ -1854,9 +1870,9 @@ long cm_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp) extern int afsd_shutdown(int); extern int afs_shutdown; -long cm_IoctlShutdown(smb_ioctl_t *ioctlp, cm_user_t *userp) -{ +long cm_IoctlShutdown(smb_ioctl_t *ioctlp, cm_user_t *userp) { afs_shutdown = 1; /* flag to shut down */ return 0; } #endif /* DJGPP */ + diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index ee5b338..04ba13b 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -125,6 +125,9 @@ extern long cm_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp); extern long cm_IoctlShutdown(smb_ioctl_t *ioctlp, cm_user_t *userp); +extern long cm_IoctlFreemountAddCell(smb_ioctl_t *ioctlp, cm_user_t *userp); + +extern long cm_IoctlFreemountRemoveCell(smb_ioctl_t *ioctlp, cm_user_t *userp); #endif /* __CM_IOCTL_INTERFACES_ONLY__ */ diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 759a31f..d3add60 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -43,6 +43,10 @@ osi_rwlock_t cm_scacheLock; /* Dummy scache entry for use with pioctl fids */ cm_scache_t cm_fakeSCache; +#ifdef AFS_FREELANCE_CLIENT +extern osi_mutex_t cm_Freelance_Lock; +#endif + /* must be called with cm_scacheLock write-locked! */ void cm_AdjustLRU(cm_scache_t *scp) { @@ -236,11 +240,16 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, long code; cm_volume_t *volp; cm_cell_t *cellp; + char* mp; + int special; // yj: boolean variable to test if file is on root.afs + int isRoot; hash = CM_SCACHE_HASH(fidp); osi_assert(fidp->cell != 0); + // yj: check if we have the scp, if so, we don't need + // to do anything else lock_ObtainWrite(&cm_scacheLock); for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { @@ -252,18 +261,85 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, } } - /* otherwise, we need to find the volume */ - lock_ReleaseWrite(&cm_scacheLock); /* for perf. reasons */ - cellp = cm_FindCellByID(fidp->cell); - if (!cellp) return CM_ERROR_NOSUCHCELL; + // yj: when we get here, it means we don't have an scp + // so we need to either load it or fake it, depending + // on whether the file is "special", see below. + + // yj: if we're trying to get an scp for a file that's + // on root.afs of homecell, we want to handle it specially + // because we have to fill in the status stuff 'coz we + // don't want trybulkstat to fill it in for us +#ifdef AFS_FREELANCE_CLIENT + special = (fidp->cell==0x1 && fidp->volume==0x20000001 && + !(fidp->vnode==0x1 && fidp->unique==0x1)); + isRoot = (fidp->cell==0x1 && fidp->volume==0x20000001 && + fidp->vnode==0x1 && fidp->unique==0x1); + if (cm_freelanceEnabled && isRoot) { + /* freelance: if we are trying to get the root scp for the first + time, we will just put in a place holder entry. */ + volp = NULL; + } + + if (cm_freelanceEnabled && special) { + /*afsi_log("cm_getscache: special"); */ + lock_ObtainMutex(&cm_Freelance_Lock); + mp =(cm_localMountPoints+fidp->vnode-2)->mountPointStringp; + lock_ReleaseMutex(&cm_Freelance_Lock); + + scp = cm_GetNewSCache(); + + scp->fid = *fidp; + scp->volp = cm_rootSCachep->volp; + if (scp->dotdotFidp == (cm_fid_t *) NULL) + scp->dotdotFidp = (cm_fid_t *) malloc (sizeof(cm_fid_t)); + scp->dotdotFidp->cell=0x1; + scp->dotdotFidp->volume=0x20000001; + scp->dotdotFidp->unique=1; + scp->dotdotFidp->vnode=1; + scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO); + scp->nextp=cm_hashTablep[hash]; + cm_hashTablep[hash]=scp; + scp->flags |= CM_SCACHEFLAG_INHASH; + scp->refCount = 1; + scp->fileType = CM_SCACHETYPE_MOUNTPOINT; + + lock_ObtainMutex(&cm_Freelance_Lock); + scp->length.LowPart = strlen(mp)+4; + scp->mountPointStringp=malloc(strlen(mp)); + strcpy(scp->mountPointStringp,mp); + lock_ReleaseMutex(&cm_Freelance_Lock); + + scp->owner=0x0; + scp->unixModeBits=0x1ff; + scp->clientModTime=0x3b49f6e2; + scp->serverModTime=0x3b49f6e2; + scp->parentUnique = 0x1; + scp->parentVnode=0x1; + scp->group=0; + scp->dataVersion=0x8; + *outScpp = scp; + lock_ReleaseWrite(&cm_scacheLock); + /*afsi_log(" getscache done");*/ + return 0; - code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp); - if (code) return code; + } + // end of yj code +#endif /* AFS_FREELANCE_CLIENT */ + + /* otherwise, we need to find the volume */ + if (!cm_freelanceEnabled || !isRoot) { + lock_ReleaseWrite(&cm_scacheLock); /* for perf. reasons */ + cellp = cm_FindCellByID(fidp->cell); + if (!cellp) return CM_ERROR_NOSUCHCELL; + + code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp); + if (code) return code; + lock_ObtainWrite(&cm_scacheLock); + } /* otherwise, we have the volume, now reverify that the scp doesn't * exist, and proceed. */ - lock_ObtainWrite(&cm_scacheLock); for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { scp->refCount++; @@ -281,20 +357,22 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, scp->fid = *fidp; scp->volp = volp; /* a held reference */ - /* if this scache entry represents a volume root then we need - * to copy the dotdotFipd from the volume structure where the - * "master" copy is stored (defect 11489) - */ - if(scp->fid.vnode == 1 && scp->fid.unique == 1 && volp->dotdotFidp) { - if (scp->dotdotFidp == (cm_fid_t *) NULL) - scp->dotdotFidp = (cm_fid_t *) malloc(sizeof(cm_fid_t)); - *(scp->dotdotFidp) = *volp->dotdotFidp; + if (!cm_freelanceEnabled || !isRoot) { + /* if this scache entry represents a volume root then we need + * to copy the dotdotFipd from the volume structure where the + * "master" copy is stored (defect 11489) + */ + if(scp->fid.vnode == 1 && scp->fid.unique == 1 && volp->dotdotFidp) { + if (scp->dotdotFidp == (cm_fid_t *) NULL) + scp->dotdotFidp = (cm_fid_t *) malloc(sizeof(cm_fid_t)); + *(scp->dotdotFidp) = *volp->dotdotFidp; + } + + if (volp->roID == fidp->volume) + scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO); + else if (volp->bkID == fidp->volume) + scp->flags |= CM_SCACHEFLAG_RO; } - - if (volp->roID == fidp->volume) - scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO); - else if (volp->bkID == fidp->volume) - scp->flags |= CM_SCACHEFLAG_RO; scp->nextp = cm_hashTablep[hash]; cm_hashTablep[hash] = scp; scp->flags |= CM_SCACHEFLAG_INHASH; @@ -504,7 +582,16 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp, goto sleep; } - if (flags & CM_SCACHESYNC_NEEDCALLBACK) { + // yj: modified this so that callback only checked if we're + // not checking something on /afs + if ( (flags & CM_SCACHESYNC_NEEDCALLBACK) +#ifdef AFS_FREELANCE_CLIENT + && (!cm_freelanceEnabled || !(!(scp->fid.vnode==0x1 && + scp->fid.unique==0x1) && + scp->fid.cell==0x1 && + scp->fid.volume==0x20000001)) +#endif /* AFS_FREELANCE_CLIENT */ + ) { if (!cm_HaveCallback(scp)) { osi_Log1(afsd_logp, "CM SyncOp getting callback on scp %x", (long) scp); @@ -703,6 +790,31 @@ void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, long flags) void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp, cm_user_t *userp, int flags) { + // yj: i want to create some fake status for the /afs directory and the + // entries under that directory +#ifdef AFS_FREELANCE_CLIENT + if (cm_freelanceEnabled && scp == cm_rootSCachep) { + statusp->InterfaceVersion = 0x1; + statusp->FileType = 0x2; + statusp->LinkCount = scp->linkCount; + statusp->Length = cm_fakeDirSize; + statusp->DataVersion = cm_fakeDirVersion; + statusp->Author = 0x1; + statusp->Owner = 0x0; + statusp->CallerAccess = 0x9; + statusp->AnonymousAccess = 0x9; + statusp->UnixModeBits = 0x1ff; + statusp->ParentVnode = 0x1; + statusp->ParentUnique = 0x1; + statusp->SegSize = 0; + statusp->ClientModTime = 0x3b49f6e2; + statusp->ServerModTime = 0x3b49f6e2; + statusp->Group = 0; + statusp->SyncCounter = 0; + statusp->dataVersionHigh = 0; + } +#endif /* AFS_FREELANCE_CLIENT */ + if (!(flags & CM_MERGEFLAG_FORCE) && statusp->DataVersion < (unsigned long) scp->dataVersion) { struct cm_cell *cellp; diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 440d34d..e29d89d 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1059,6 +1059,14 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp) AFSFetchStatus newDirStatus; AFSVolSync volSync; +#ifdef AFS_FREELANCE_CLIENT + if (cm_freelanceEnabled && dscp == cm_rootSCachep) { + /* deleting a mount point from the root dir. */ + code = cm_FreelanceRemoveMount(namep); + return code; + } +#endif + /* make sure we don't screw up the dir status during the merge */ lock_ObtainMutex(&dscp->mx); sflags = CM_SCACHESYNC_STOREDATA; @@ -1499,6 +1507,21 @@ long cm_TryBulkProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, cm_ReleaseSCache(tscp); } /* found entry */ +#ifdef AFS_FREELANCE_CLIENT + // yj: if this is a mountpoint under root.afs then we don't want it + // to be bulkstat-ed, instead, we call getSCache directly and under + // getSCache, it is handled specially. + if (cm_freelanceEnabled && + tfid.cell==0x1 && tfid.volume==0x20000001 && + !(tfid.vnode==0x1 && tfid.unique==0x1) ) + { +#ifdef DEBUG + afsi_log(" cm_trybulkproc going to call getscache"); +#endif + return cm_GetSCache(&tfid, &tscp, NULL, NULL); + } +#endif /* AFS_FREELANCE_CLIENT */ + i = bsp->counter++; bsp->fids[i].Volume = scp->fid.volume; bsp->fids[i].Vnode = tfid.vnode; diff --git a/src/WINNT/afsd/libafsconf.def b/src/WINNT/afsd/libafsconf.def index b0b7bc9..08c2d1e 100644 --- a/src/WINNT/afsd/libafsconf.def +++ b/src/WINNT/afsd/libafsconf.def @@ -17,3 +17,7 @@ EXPORTS cm_AppendNewCell @10 cm_AppendNewCellLine @11 cm_CloseCellFile @12 + cm_SearchCellByDNS @13 + getAFSServer @14 + cm_InitDNS @15 + cm_GetConfigDir @16 diff --git a/src/WINNT/client_osi/osisleep.h b/src/WINNT/client_osi/osisleep.h index aaf0c8f..efeb5eb 100644 --- a/src/WINNT/client_osi/osisleep.h +++ b/src/WINNT/client_osi/osisleep.h @@ -82,8 +82,10 @@ extern void osi_SleepSpin(long value, Crit_Sec *counterp); /* spin lock version of wakeup, used internally only */ extern void osi_WakeupSpin(long value); +#ifndef DJGPP /* exported function to sleep on a value */ extern void osi_Sleep (long); +#endif extern void osi_FreeSleepInfo(osi_sleepInfo_t *); diff --git a/src/auth/NTMakefile b/src/auth/NTMakefile index 5d9cb48..5ff836a 100644 --- a/src/auth/NTMakefile +++ b/src/auth/NTMakefile @@ -74,7 +74,8 @@ EXELIBS =\ $(EXELIBDIR)\afslwp.lib \ $(EXELIBDIR)\afs\afsutil.lib \ $(DESTDIR)\lib\afs\afseventlog.lib \ - $(EXELIBDIR)\afs\afsreg.lib + $(EXELIBDIR)\afs\afsreg.lib \ + $(DESTDIR)\lib\cm_dns.obj $(SETKEY_EXEFILE): $(SETKEY_EXEOBJS) $(EXELIBS) diff --git a/src/auth/cellconfig.c b/src/auth/cellconfig.c index ed47eeb..9eb77da 100644 --- a/src/auth/cellconfig.c +++ b/src/auth/cellconfig.c @@ -24,6 +24,9 @@ RCSID("$Header$"); #include #include #include +#ifdef AFS_AFSDB_ENV +#include +#endif /* AFS_AFSDB_ENV */ #else #include #include @@ -56,6 +59,7 @@ RCSID("$Header$"); #include #include "cellconfig.h" #include "keys.h" +#include static ParseHostLine(); static ParseCellLine(); @@ -364,9 +368,12 @@ char clones[]; #else i = GetCellUnix(adir); #endif + +#ifndef AFS_FREELANCE_CLIENT /* no local cell not fatal in freelance */ if (i) { return i; } +#endif /* now parse the individual lines */ curEntry = 0; @@ -564,6 +571,7 @@ afsconf_GetExtendedCellInfo(adir, acellName, aservice, acellInfo, clones) } #ifdef AFS_AFSDB_ENV +#if !defined(AFS_NT40_ENV) afsconf_GetAfsdbInfo(acellName, aservice, acellInfo) char *acellName; char *aservice; @@ -656,6 +664,58 @@ afsconf_GetAfsdbInfo(acellName, aservice, acellInfo) return 0; } +#else /* windows */ +int afsconf_GetAfsdbInfo(acellName, aservice, acellInfo) + char *aservice; + char *acellName; + struct afsconf_cell *acellInfo; +{ + register afs_int32 i; + int tservice; + struct afsconf_entry DNSce; + char *DNStmpStrp; /* a temp string pointer */ + struct hostent *thp; + afs_int32 cellHosts[AFSMAXCELLHOSTS]; + int numServers; + int rc; + int *ttl; + + DNSce.cellInfo.numServers=0; + DNSce.next = NULL; + rc = getAFSServer(acellName, cellHosts, &numServers, &ttl); + /* ignore the ttl here since this code is only called by transitory programs + like klog, etc. */ + if (rc < 0) + return -1; + if (numServers == 0) + return -1; + + for (i = 0; i < numServers; i++) + { + memcpy(&acellInfo->hostAddr[i].sin_addr.s_addr, &cellHosts[i], sizeof(long)); + acellInfo->hostAddr[i].sin_family = AF_INET; + + /* sin_port supplied by connection code */ + } + + acellInfo->numServers = numServers; + strcpy(acellInfo->name, acellName); + if (aservice) { + LOCK_GLOBAL_MUTEX + tservice = afsconf_FindService(aservice); + UNLOCK_GLOBAL_MUTEX + if (tservice < 0) { + return AFSCONF_NOTFOUND; /* service not found */ + } + for(i=0; i< acellInfo->numServers; i++) { + acellInfo->hostAddr[i].sin_port = tservice; + } + } + acellInfo->linkedCell = NULL; /* no linked cell */ + acellInfo->flags = 0; + return 0; +} +#endif /* windows */ #endif /* AFS_AFSDB_ENV */ afsconf_GetCellInfo(adir, acellName, aservice, acellInfo) diff --git a/src/config/Makefile.i386_djgpp b/src/config/Makefile.i386_djgpp index 7206ea9..ddbacc3 100644 --- a/src/config/Makefile.i386_djgpp +++ b/src/config/Makefile.i386_djgpp @@ -15,7 +15,7 @@ AFS_OSTYPE = DJGPP OPTMZ=-O2 #PAM_CFLAGS = -O2 -Dlinux -DLINUX_PAM -fPIC # Put -O2 here to _ensure_ all Makefiles pick it up. -XCFLAGS= ${DBG} -Dfds_bits=fd_bits +XCFLAGS= ${DBG} -Dfds_bits=fd_bits -DAFS_AFSDB_ENV -DAFS_FREELANCE_CLIENT MT_CFLAGS=${XCFLAGS} XLDFLAGS= SHARE_LDFLAGS = -shared -Xlinker -x diff --git a/src/config/NTMakefile.i386_nt40 b/src/config/NTMakefile.i386_nt40 index 83cce89..2d48de1 100644 --- a/src/config/NTMakefile.i386_nt40 +++ b/src/config/NTMakefile.i386_nt40 @@ -152,7 +152,9 @@ afscdefs =\ -I$(DESTDIR)\include\rx \ -DWIN32_LEAN_AND_MEAN \ -DSTRICT \ - -D_WIN32_IE=0x0400 + -D_WIN32_IE=0x0400 \ + -DAFS_AFSDB_ENV \ + -DAFS_FREELANCE_CLIENT afscdefs = $(afscdefs) $(AFSDEV_AUXCDEFINES) diff --git a/src/config/NTMakefile.i386_win95 b/src/config/NTMakefile.i386_win95 index 2c31415..176015c 100644 --- a/src/config/NTMakefile.i386_win95 +++ b/src/config/NTMakefile.i386_win95 @@ -164,7 +164,9 @@ afscdefs =\ -I$(DESTDIR)\include\rx \ -DWIN32_LEAN_AND_MEAN \ -DSTRICT \ - -D_WIN32_IE=0x0400 + -D_WIN32_IE=0x0400 \ + -DAFS_AFSDB_ENV \ + -DAFS_FREELANCE_CLIENT ! IF ((EXIST($(MSSDK)\include)) && (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" ))) afscdefs=$(afscdefs) -I$(MSSDK)\include $(afscppdefs) \ diff --git a/src/config/afsconfig-windows.h b/src/config/afsconfig-windows.h index 9237e56..6168147 100644 --- a/src/config/afsconfig-windows.h +++ b/src/config/afsconfig-windows.h @@ -194,7 +194,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #undef HAVE_RES_SEARCH //#undef HAVE_SOCKET -#if ENDIANESS_IN_SYS_PARAM_H +#ifdef ENDIANESS_IN_SYS_PARAM_H # ifndef KERNEL # include # include @@ -204,7 +204,8 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } # endif #endif -#undef AFS_AFSDB_ENV +/*#undef AFS_AFSDB_ENV*/ +#define AFS_AFSDB_ENV 1 #undef AFS_NAMEI_ENV #undef BOS_RESTRICTED_MODE diff --git a/src/kauth/NTMakefile b/src/kauth/NTMakefile index def0154..02577f9 100644 --- a/src/kauth/NTMakefile +++ b/src/kauth/NTMakefile @@ -94,7 +94,8 @@ AFSLIBS = \ $(DESTDIR)\lib\afsrx.lib \ $(DESTDIR)\lib\afsubik.lib \ $(DESTDIR)\lib\afs\afseventlog.lib \ - $(DESTDIR)\lib\afsrxkad.lib + $(DESTDIR)\lib\afsrxkad.lib \ + $(DESTDIR)\lib\cm_dns.obj TOKENLIB = $(DESTDIR)\lib\afs\afspioctl.lib diff --git a/src/kauth/kpasswd.c b/src/kauth/kpasswd.c index b524cfc..a615470 100644 --- a/src/kauth/kpasswd.c +++ b/src/kauth/kpasswd.c @@ -247,8 +247,10 @@ CommandProc (as, arock) code = ka_Init(0); if (code || !(lcell = ka_LocalCell())) { +#ifndef AFS_FREELANCE_CLIENT if (!Pipe) com_err (rn, code , "Can't get local cell name!"); exit (1); +#endif } code = rx_Init(0); @@ -353,7 +355,15 @@ CommandProc (as, arock) memset(as->parms[aNEWPASSWORD].items->data, 0, strlen(as->parms[aNEWPASSWORD].items->data)); } +#ifdef AFS_FREELANCE_CLIENT + if (!foundExplicitCell && !lcell) { + if (!Pipe) com_err (rn, code, "no cell name provided"); + exit(1); + } +#else if (!foundExplicitCell) strcpy (realm, lcell); +#endif /* freelance */ + if (code = ka_CellToRealm (realm, realm, &local)) { if (!Pipe) com_err (rn, code, "Can't convert cell to realm"); exit (1); diff --git a/src/kauth/user_nt.c b/src/kauth/user_nt.c index a62e378..c37c66d 100644 --- a/src/kauth/user_nt.c +++ b/src/kauth/user_nt.c @@ -96,6 +96,7 @@ afs_int32 ka_UserAuthenticateGeneral( char fullRealm[256]; char upperRealm[256]; struct servent *sp; + int ttl; struct ktc_principal server; struct ktc_principal client; @@ -106,6 +107,11 @@ afs_int32 ka_UserAuthenticateGeneral( code = cm_SearchCellFile(realm, fullRealm, ka_AddHostProc, NULL); +#ifdef AFS_AFSDB_ENV + if (code) { + code = cm_SearchCellByDNS(realm, fullRealm, &ttl, ka_AddHostProc, NULL); + } +#endif if (code) { *reasonP = "specified realm is unknown"; return (code); @@ -310,24 +316,27 @@ static check_response ptr = (char *) cip->dat + 8; /* Check and extract server's name */ - if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) { return(INTK_BADPW); + } (void) strncpy(s_service, ptr, sizeof(s_service)-1); s_service[sizeof(s_service)-1] = '\0'; ptr += strlen(s_service) + 1; /* Check and extract server's instance */ - if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) { return(INTK_BADPW); + } (void) strncpy(s_instance,ptr, sizeof(s_instance)-1); s_instance[sizeof(s_instance)-1] = '\0'; ptr += strlen(s_instance) + 1; /* Check and extract server's realm */ - if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) + if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) { return(INTK_BADPW); + } (void) strncpy(s_realm,ptr, sizeof(s_realm)); s_realm[sizeof(s_realm)-1] = '\0'; @@ -340,8 +349,9 @@ static check_response ticket_len = (unsigned char) *ptr++; if ((ticket_len < 0) || - ((ticket_len + (ptr - (char *) cip->dat)) > (int) cip->length)) + ((ticket_len + (ptr - (char *) cip->dat)) > (int) cip->length)) { return(INTK_BADPW); + } /* Check returned server name, instance, and realm fields */ /* diff --git a/src/libafsauthent/NTMakefile b/src/libafsauthent/NTMakefile index 4182a21..c739b87 100644 --- a/src/libafsauthent/NTMakefile +++ b/src/libafsauthent/NTMakefile @@ -90,6 +90,7 @@ DLLOBJS =\ $(SYSOBJS) \ $(WINNTAFSDOBJS) \ $(AUDITOBJS) \ + $(DESTDIR)\lib\cm_dns.obj \ afsauthent.res audit.obj: $(AUDIT)\audit.c @@ -231,4 +232,4 @@ install: $(LIBFILE) install9x: install clean :: - $(DEL) $(LIBFILE) \ No newline at end of file + $(DEL) $(LIBFILE) diff --git a/src/ptserver/NTMakefile b/src/ptserver/NTMakefile index 02ea656..1e277f0 100644 --- a/src/ptserver/NTMakefile +++ b/src/ptserver/NTMakefile @@ -65,7 +65,8 @@ PTSERVER_EXELIBS =\ $(DESTDIR)\lib\afs\afsutil.lib \ $(DESTDIR)\lib\afs\afsaudit.lib \ $(DESTDIR)\lib\afs\afseventlog.lib \ - $(DESTDIR)\lib\afs\afsreg.lib + $(DESTDIR)\lib\afs\afsreg.lib \ + $(DESTDIR)\lib\cm_dns.obj !IF (("$(SYS_NAME)"!="i386_win95" ) && ("$(SYS_NAME)"!="I386_WIN95" )) PTSERVER_EXELIBS =$(PTSERVER_EXELIBS) $(DESTDIR)\lib\afs\afsprocmgmt.lib @@ -100,7 +101,8 @@ PTS_EXELIBS =\ $(DESTDIR)\lib\afs\afscmd.lib \ $(DESTDIR)\lib\afs\afsreg.lib \ $(DESTDIR)\lib\afs\afseventlog.lib \ - $(DESTDIR)\lib\afs\afspioctl.lib + $(DESTDIR)\lib\afs\afspioctl.lib \ + $(DESTDIR)\lib\cm_dns.obj $(PTS): $(PTS_EXEOBJS) $(PTS_EXELIBS) $(EXECONLINK) diff --git a/src/ptserver/pts.c b/src/ptserver/pts.c index 7546c9f..b6dce8a 100644 --- a/src/ptserver/pts.c +++ b/src/ptserver/pts.c @@ -833,7 +833,14 @@ int main (argc, argv) { register afs_int32 code; register struct cmd_syndesc *ts; +#ifdef WIN32 + WSADATA WSAjunk; +#endif +#ifdef WIN32 + WSAStartup(0x0101, &WSAjunk); +#endif + #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a