+Since 1.3.70:
+ * Fix aklog.exe to not add the AFS ID to the username
+
+ * PTS registration of new users to foreign cells has been added to
+ afscreds.exe
+
+ * The cm_Daemon thread is used to perform checks for
+ down servers, up servers, volumes, callback expirations,
+ lock maintenance and token expiration. Due to a gaff in
+ larger integer division the thread never performed any
+ work. Instead the current time computation would always
+ be less then the trigger times. This had an adverse affect
+ on the client's ability to maintain communication with servers,
+ keep volumes up to date, and flush user tokens and acls
+ when they have expired. This was broken when the 1.3 branch
+ was modified to support VC7 which no longer included
+ largeint.lib
+
+ * An initialization problem with the Freelance code was
+ detected while fixing the callbackRequest. The cm_rootSCachep
+ object is obtained during afsd_InitDaemons() but the callback
+ information is incomplete. The callback information will not
+ be obtained until cm_MergeStatus is called from within
+ cm_GetCallback. Unfortunately, cm_SyncOp did not properly
+ test for the conditions under which the callback information
+ must be obtained.
+
+ * Reports have been filed indicating that callbacks were
+ being lost. An examination of the code indicated that the
+ cm_server_t objects were not being properly reference
+ counted by the cm_scache_t and cm_callbackRequest_t objects.
+ In particular, the cm_server_t objects may have been freed
+ from beneath the cm_conn_t objects.
+
+ All of the reference counting is now done via the functions:
+ cm_GetServer
+ cm_GetServerNoLock
+ cm_PutServer
+ cm_PutServerNoLock
+ this improves the ability to track the referrals.
+
+ Each cm_BeginCallbackGranting Call now allocates a reference
+ to the cm_server_t. The cm_EndCallbackGrantingCall either
+ frees the reference or transfers it to the cm_scache_t
+ cbServerp field. These are then appropriately tracked
+ through the cm_Analyze call.
+
+ * Ensure that the dnlc hash table is the same size as the
+ dir name hash table (as per original author's note).
+ Increase the dnlc CM_AFSNCNAMESIZE to a multiple of 8
+ for compatibility with 64-bit systems.
+
+ * fix smb_ApplyV3DirListPatches to properly apply the hidden
+ attribute to dotfiles when the infoLevel < 0x101 and
+ cm_SyncOp has failed.
+
+ * Fix the Freelance registry initialization code. There
+ was a possibility that some systems could end up with
+ garbage in the registry during a clean install.
+
Since 1.3.66:
* file and directory names beginning with "." will now be given the
hidden attribute when the volume access is anonymous. this matches
afsmap.exe <drive> <afs-path> [/PERSISTENT]
afsmap.exe <drive> <unc-path> [/PERSISTENT]
afsmap.exe <drive> /DELETE
+ 23. Write-through caching appears to be unsupported. Files copied to AFS
+ do not end up in the local cache.
cm_volume_t *cm_rootVolumep = NULL;
cm_cell_t *cm_rootCellp = NULL;
cm_fid_t cm_rootFid;
-cm_scache_t *cm_rootSCachep;
+cm_scache_t *cm_rootSCachep = NULL;
char cm_mountRoot[1024];
DWORD cm_mountRootLen;
int cm_logChunkSize;
char cm_NetbiosName[MAX_NB_NAME_LENGTH] = "";
-char cm_CachePath[200];
+char cm_CachePath[MAX_PATH];
DWORD cm_CachePathLen;
BOOL isGateway = FALSE;
code = RegQueryValueEx(parmKey, "LogoffTokenTransferTimeout",
NULL, NULL, (BYTE *) <to, &dummyLen);
if (code == ERROR_SUCCESS)
- afsi_log("Logoff token tranfer timeout %d seconds",
- ltto);
+ afsi_log("Logoff token tranfer timeout %d seconds", ltto);
else {
ltto = 10;
afsi_log("Default logoff token transfer timeout 10 seconds");
cm_sysName = cm_sysNameList[0];
dummyLen = MAXSYSNAME;
- code = RegQueryValueEx(parmKey, "SysName", NULL, NULL,
- cm_sysName, &dummyLen);
+ code = RegQueryValueEx(parmKey, "SysName", NULL, NULL, cm_sysName, &dummyLen);
if (code == ERROR_SUCCESS)
afsi_log("Sys name %s", cm_sysName);
else {
}
}
+
#ifdef AFS_FREELANCE_CLIENT
if (cm_freelanceEnabled)
cm_InitFreelance();
#endif
-
return 0;
}
#include <osilog.h>
#include <rxkad_prototypes.h> /* for life_to_time */
+#include <afs/ptserver.h>
/*
* TIMING _____________________________________________________________________
return(0);
}
+
+#define ALLOW_REGISTER 1
+static int
+ViceIDToUsername(char *username,
+ char *realm_of_user,
+ char *realm_of_cell,
+ char * cell_to_use,
+ struct ktc_principal *aclient,
+ struct ktc_principal *aserver,
+ struct ktc_token *atoken)
+{
+ static char lastcell[MAXCELLCHARS+1] = { 0 };
+ static char confname[512] = { 0 };
+ char username_copy[BUFSIZ];
+ long viceId; /* AFS uid of user */
+ int status = 0;
+#ifdef ALLOW_REGISTER
+ afs_int32 id;
+#endif /* ALLOW_REGISTER */
+
+ if (confname[0] == '\0') {
+ strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
+ confname[sizeof(confname) - 2] = '\0';
+ }
+
+ /*
+ * Talk about DUMB! It turns out that there is a bug in
+ * pr_Initialize -- even if you give a different cell name
+ * to it, it still uses a connection to a previous AFS server
+ * if one exists. The way to fix this is to change the
+ * _filename_ argument to pr_Initialize - that forces it to
+ * re-initialize the connection. We do this by adding and
+ * removing a "/" on the end of the configuration directory name.
+ */
+
+ if (lastcell[0] != '\0' && (strcmp(lastcell, aserver->cell) != 0)) {
+ int i = strlen(confname);
+ if (confname[i - 1] == '/') {
+ confname[i - 1] = '\0';
+ } else {
+ confname[i] = '/';
+ confname[i + 1] = '\0';
+ }
+ }
+
+ strcpy(lastcell, aserver->cell);
+
+ if (!pr_Initialize (0, confname, aserver->cell))
+ status = pr_SNameToId (username, &viceId);
+
+ /*
+ * This is a crock, but it is Transarc's crock, so
+ * we have to play along in order to get the
+ * functionality. The way the afs id is stored is
+ * as a string in the username field of the token.
+ * Contrary to what you may think by looking at
+ * the code for tokens, this hack (AFS ID %d) will
+ * not work if you change %d to something else.
+ */
+
+ /*
+ * This code is taken from cklog -- it lets people
+ * automatically register with the ptserver in foreign cells
+ */
+
+#ifdef ALLOW_REGISTER
+ if (status == 0) {
+ if (viceId != ANONYMOUSID) {
+#else /* ALLOW_REGISTER */
+ if ((status == 0) && (viceId != ANONYMOUSID))
+#endif /* ALLOW_REGISTER */
+ {
+#ifdef AFS_ID_TO_NAME
+ strncpy(username_copy, username, BUFSIZ);
+ snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
+#endif /* AFS_ID_TO_NAME */
+ }
+#ifdef ALLOW_REGISTER
+ } else if (strcmp(realm_of_user, realm_of_cell) != 0) {
+ id = 0;
+ strncpy(aclient->name, username, MAXKTCNAMELEN - 1);
+ strcpy(aclient->instance, "");
+ strncpy(aclient->cell, realm_of_user, MAXKTCREALMLEN - 1);
+ if (status = ktc_SetToken(aserver, atoken, aclient, 0))
+ return status;
+
+ /*
+ * In case you're wondering, we don't need to change the
+ * filename here because we're still connecting to the
+ * same cell -- we're just using a different authentication
+ * level
+ */
+
+ if (status = pr_Initialize(1L, confname, aserver->cell, 0))
+ return status;
+ if (status = pr_CreateUser(username, &id))
+ return status;
+#ifdef AFS_ID_TO_NAME
+ strncpy(username_copy, username, BUFSIZ);
+ snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
+#endif /* AFS_ID_TO_NAME */
+ }
+ }
+#endif /* ALLOW_REGISTER */
+ return status;
+}
+
+
int
KFW_AFS_klog(
krb5_context alt_ctx,
p[len] = '\0';
}
+ ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
+ &aclient, &aserver, &atoken);
+
if ( smbname ) {
strncpy(aclient.smbname, smbname, sizeof(aclient.smbname));
aclient.smbname[sizeof(aclient.smbname)-1] = '\0';
strcpy(aclient.cell, CellName);
+ ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
+ &aclient, &aserver, &atoken);
+
if ( smbname ) {
strncpy(aclient.smbname, smbname, sizeof(aclient.smbname));
aclient.smbname[sizeof(aclient.smbname)-1] = '\0';
/* fall through */
done:
- if (didLock) lock_ReleaseMutex(&aclScp->mx);
+ if (didLock)
+ lock_ReleaseMutex(&aclScp->mx);
cm_ReleaseSCache(aclScp);
return code;
}
*/
long buf_SetNBuffers(long nbuffers)
{
- if (nbuffers < 10) return CM_ERROR_INVAL;
- if (nbuffers == buf_nbuffers) return 0;
+ if (nbuffers < 10)
+ return CM_ERROR_INVAL;
+ if (nbuffers == buf_nbuffers)
+ return 0;
else if (nbuffers > buf_nbuffers)
return buf_AddBuffers(nbuffers - buf_nbuffers);
- else return CM_ERROR_INVAL;
+ else
+ return CM_ERROR_INVAL;
}
/* release a buffer. Buffer must be referenced, but unlocked. */
* have any lock conflicts, so we can grab the buffer lock out of
* order in the locking hierarchy.
*/
- osi_Log2(buf_logp,
- "buf_Recycle recycles 0x%x, off 0x%x",
+ osi_Log2( buf_logp, "buf_Recycle recycles 0x%x, off 0x%x",
bp, bp->offset.LowPart);
osi_assert(bp->refCount == 0);
}
lock_ReleaseWrite(&buf_globalLock);
-
}
lock_ReleaseMutex(&scp->mx);
*/
struct cm_buf *allp; /* next in all list */
osi_mutex_t mx; /* mutex protecting structure except refcount */
- int refCount; /* reference count */
+ int refCount; /* reference count (buf_globalLock) */
long idCounter; /* counter for softrefs; bumped at each recycle */
long dirtyCounter; /* bumped at each dirty->clean transition */
#ifdef notdef
int fdc, fgc;
if (cm_freelanceEnabled &&
- scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
- scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) { // if it's something on /afs
- if (!(scp->fid.vnode==0x1 && scp->fid.unique==0x1)) // if it's not root.afs
+ scp->fid.cell==AFS_FAKE_ROOT_CELL_ID && scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
+ /* 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;
}
return 0;
}
- }
#endif
if (scp->cbServerp != NULL)
return 1;
- else return 0;
+ else
+ return 0;
}
/* need to detect a broken callback that races with our obtaining a callback.
cm_racingRevokes_t *revp; /* where we are */
cm_racingRevokes_t *nrevp; /* where we'll be next */
int freeFlag;
+ cm_server_t * serverp = 0;
lock_ObtainWrite(&cm_callbackLock);
if (flags & CM_CALLBACK_MAINTAINCOUNT) {
else {
osi_assert(cm_activeCallbackGrantingCalls-- > 0);
}
- if (cm_activeCallbackGrantingCalls == 0) freeFlag = 1;
- else freeFlag = 0;
+ if (cm_activeCallbackGrantingCalls == 0)
+ freeFlag = 1;
+ else
+ freeFlag = 0;
/* record the callback; we'll clear it below if we really lose it */
+ if (cbrp) {
if (scp) {
+ if (scp->cbServerp != cbrp->serverp) {
+ serverp = scp->cbServerp;
+ }
scp->cbServerp = cbrp->serverp;
scp->cbExpires = cbrp->startTime + cbp->ExpirationTime;
+ } else {
+ serverp = cbrp->serverp;
+ }
+ cbrp->serverp = NULL;
}
/* a callback was actually revoked during our granting call, so
* callback-granting call, and if this fid is the right fid,
* then clear the callback.
*/
- if (scp && cbrp->callbackCount != cm_callbackCount
+ if (scp && cbrp && cbrp->callbackCount != cm_callbackCount
&& revp->callbackCount > cbrp->callbackCount
&& (( scp->fid.volume == revp->fid.volume &&
scp->fid.vnode == revp->fid.vnode &&
if (freeFlag) cm_racingRevokesp = NULL;
lock_ReleaseWrite(&cm_callbackLock);
+
+ if ( serverp ) {
+ lock_ObtainWrite(&cm_serverLock);
+ cm_FreeServer(serverp);
+ lock_ReleaseWrite(&cm_serverLock);
+ }
}
/* if flags is 1, we want to force the code to make one call, anyway.
scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
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);
+ osi_Log0(afsd_logp,"cm_getGetCallback fakeGettingCallback=1");
cm_fakeGettingCallback = 1;
lock_ReleaseMutex(&cm_Freelance_Lock);
// Indicate that the callback is not done
lock_ObtainMutex(&cm_Freelance_Lock);
+ osi_Log0(afsd_logp,"cm_getGetCallback fakeDirCallback=2");
cm_fakeDirCallback = 2;
+
// Indicate that we're no longer fetching the callback
+ osi_Log0(afsd_logp,"cm_getGetCallback fakeGettingCallback=0");
cm_fakeGettingCallback = 0;
lock_ReleaseMutex(&cm_Freelance_Lock);
cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0);
}
else
- cm_EndCallbackGrantingCall(NULL, NULL, NULL, 0);
+ cm_EndCallbackGrantingCall(NULL, &cbr, NULL, 0);
/* now check to see if we got an error */
if (code) return code;
scp->refCount++;
lock_ReleaseWrite(&cm_scacheLock);
lock_ObtainMutex(&scp->mx);
- if (scp->cbServerp && now > scp->cbExpires) {
- osi_Log1(afsd_logp, "Discarding SCache scp %x", scp);
+ if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) {
+ osi_Log1(afsd_logp, "Callback Expiration Discarding SCache scp %x", scp);
cm_DiscardSCache(scp);
}
lock_ReleaseMutex(&scp->mx);
extern void cm_CheckCBExpiration(void);
+extern osi_rwlock_t cm_callbackLock;
+
#endif /* _CM_CALLBACK_H_ENV__ */
#else
gettimeofday(&reqp->startTime, NULL);
#endif
-
}
static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
cm_serverRef_t * serversp,
cm_callbackRequest_t *cbrp, long errorCode)
{
- cm_server_t *serverp;
+ cm_server_t *serverp = 0;
cm_serverRef_t **serverspp = 0;
cm_serverRef_t *tsrp;
cm_ucell_t *ucellp;
serverp = connp->serverp;
/* Update callback pointer */
- if (cbrp && errorCode == 0)
- cbrp->serverp = connp->serverp;
+ if (cbrp && serverp && errorCode == 0) {
+ if (cbrp->serverp) {
+ if ( cbrp->serverp != serverp ) {
+ lock_ObtainWrite(&cm_serverLock);
+ cm_PutServerNoLock(cbrp->serverp);
+ cm_GetServerNoLock(serverp);
+ lock_ReleaseWrite(&cm_serverLock);
+ }
+ } else {
+ cm_GetServer(serverp);
+ }
+ lock_ObtainWrite(&cm_callbackLock);
+ cbrp->serverp = serverp;
+ lock_ReleaseWrite(&cm_callbackLock);
+ }
/* If not allowed to retry, don't */
if (reqp->flags & CM_REQ_NORETRY)
lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
tsp = tsrp->server;
- tsp->refCount++;
+ cm_GetServerNoLock(tsp);
lock_ReleaseWrite(&cm_serverLock);
if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
allDown = 0;
rx_SetConnDeadTime((*connpp)->callp, timeLeft);
rx_SetConnHardDeadTime((*connpp)->callp, (u_short) hardTimeLeft);
lock_ReleaseMutex(&(*connpp)->mx);
-
return 0;
}
if (firstError == 0)
}
}
lock_ObtainWrite(&cm_serverLock);
- osi_assert(tsp->refCount-- > 0);
+ cm_PutServerNoLock(tsp);
}
lock_ReleaseWrite(&cm_serverLock);
userp = tcp->userp;
if (userp && tcp->refCount == 0 && (userp->vcRefs == 0)) {
/* do the deletion of this guy */
+ cm_PutServer(tcp->serverp);
cm_ReleaseUser(userp);
*lcpp = tcp->nextp;
rx_DestroyConnection(tcp->callp);
lock_ObtainMutex(&userp->mx);
lock_ObtainWrite(&cm_connLock);
for(tcp = serverp->connsp; tcp; tcp=tcp->nextp) {
- if (tcp->userp == userp) break;
+ if (tcp->userp == userp)
+ break;
}
+
/* find ucell structure */
ucellp = cm_GetUCell(userp, serverp->cellp);
if (!tcp) {
+ cm_GetServer(serverp);
tcp = malloc(sizeof(*tcp));
memset(tcp, 0, sizeof(*tcp));
tcp->nextp = serverp->connsp;
/* periodic check daemon */
void cm_Daemon(long parm)
{
- long now;
- long lastLockCheck;
- long lastVolCheck;
- long lastCBExpirationCheck;
- long lastDownServerCheck;
- long lastUpServerCheck;
- long lastTokenCacheCheck;
+ unsigned long now;
+ unsigned long lastLockCheck;
+ unsigned long lastVolCheck;
+ unsigned long lastCBExpirationCheck;
+ unsigned long lastDownServerCheck;
+ unsigned long lastUpServerCheck;
+ unsigned long lastTokenCacheCheck;
char thostName[200];
- long code;
+ unsigned long code;
struct hostent *thp;
/* ping all file servers, up or down, with unauthenticated connection,
#include <winsock2.h>
#include <nb30.h>
#endif /* !DJGPP */
+#ifdef COMMENT
#include <malloc.h>
+#endif
#include <string.h>
#include <stdlib.h>
#include <osi.h>
while(length > 0) {
/* get callback so we can do a meaningful dataVersion comparison */
code = cm_SyncOp(scp, NULL, up, reqp, 0,
- CM_SCACHESYNC_NEEDCALLBACK
- | CM_SCACHESYNC_GETSTATUS);
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
scp->flags &= ~CM_SCACHEFLAG_PREFETCHING;
lock_ReleaseMutex(&scp->mx);
biop->reserved = 0;
/* first lookup the file's length, so we know when to stop */
- code = cm_SyncOp(scp, NULL, up, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK
- | CM_SCACHESYNC_GETSTATUS);
+ code = cm_SyncOp(scp, NULL, up, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
return code;
if (bufp->flags & CM_BUF_WAITING) {
osi_Wakeup((long) bufp);
}
- bufp->flags &= ~(CM_BUF_WAITING | CM_BUF_WRITING
- | CM_BUF_DIRTY);
+ bufp->flags &= ~(CM_BUF_WAITING | CM_BUF_WRITING | CM_BUF_DIRTY);
}
lock_ReleaseMutex(&bufp->mx);
#define __CM_DIR_ENV__ 1
#define CM_DIR_PAGESIZE 2048 /* bytes per page */
-#define CM_DIR_NHASHENT 128 /* entries in the hash tbl */
+#define CM_DIR_NHASHENT 256 /* entries in the hash tbl == NHSIZE */
#define CM_DIR_MAXPAGES 128 /* max pages in a dir */
#define CM_DIR_BIGMAXPAGES 1023 /* new big max pages */
#define CM_DIR_EPP 64 /* dir entries per page */
char name[16];
} cm_dirEntry_t;
+#ifdef UNUSED
typedef struct cm_dirXEntry {
/* A directory extension entry. */
char name[32];
cm_pageHeader_t header;
cm_dirEntry_t entry[1];
} cm_dirPage1_t;
+#endif /* UNUSED */
extern int cm_NameEntries(char *namep, size_t *lenp);
#include <osi.h>
#include "afsd.h"
-osi_rwlock_t cm_dnlcLock;
+static osi_rwlock_t cm_dnlcLock;
-cm_dnlcstats_t dnlcstats; /* dnlc statistics */
-int cm_useDnlc = 1; /* yes, start using the dnlc */
-int cm_debugDnlc = 0; /* debug dnlc */
+static cm_dnlcstats_t dnlcstats; /* dnlc statistics */
+static int cm_useDnlc = 1; /* yes, start using the dnlc */
+static int cm_debugDnlc = 0; /* debug dnlc */
/* Hash table invariants:
* 1. If nameHash[i] is NULL, list is empty
* 2. A single element in a hash bucket has itself as prev and next.
*/
-struct nc *ncfreelist = (struct nc *)0;
+static struct nc *ncfreelist = (struct nc *)0;
static struct nc nameCache[NCSIZE];
-struct nc* nameHash[NHSIZE];
-
+static struct nc *nameHash[NHSIZE];
#ifndef DJGPP
#define dnlcNotify(x,debug){ \
#define dnlcNotify(x,debug)
#endif /* !DJGPP */
-
static struct nc *
GetMeAnEntry()
{
#include <ctype.h>
-#define CM_AFSNCNAMESIZE 36 /* multiple of 4 */
-#define NCSIZE 300
-#define NHSIZE 256 /* must be power of 2== NHASHENT */
+#define CM_AFSNCNAMESIZE 40 /* multiple of 8 (for 64-bit) */
+#define NCSIZE 512
+#define NHSIZE 256 /* must be power of 2 == CM_DIR_NHASHENT */
struct nc {
}
// we know the fakeDir is setup properly, so we claim that we have callback
+ osi_Log0(afsd_logp,"cm_InitFakeRootDir fakeDirCallback=1");
cm_fakeDirCallback=1;
// when we get here, we've set up everything! done!
fprintf(fp,"%s#%s:root.cell.\n",rootCellName,rootCellName);
fprintf(fp,".%s%%%s:root.cell.\n",rootCellName,rootCellName);
fclose(fp);
- fopen(hdir, "r");
+ fp = fopen(hdir, "r");
} else {
fputs("0\n", fp);
fclose(fp);
ioctlp->outDatap = cp;
}
- if (tcellp) return 0;
- else return CM_ERROR_NOMORETOKENS; /* mapped to EDOM */
+ if (tcellp)
+ return 0;
+ else
+ return CM_ERROR_NOMORETOKENS; /* mapped to EDOM */
}
extern long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *namep);
cm_scacheLRULastp = (cm_scache_t *) osi_QPrev(&scp->q);
osi_QRemove((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
osi_QAdd((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
- if (!cm_scacheLRULastp) cm_scacheLRULastp = scp;
+ if (!cm_scacheLRULastp)
+ cm_scacheLRULastp = scp;
}
/* called with cm_scacheLock write-locked; find a vnode to recycle.
for (scp = cm_scacheLRULastp;
scp;
scp = (cm_scache_t *) osi_QPrev(&scp->q)) {
- if (scp->refCount == 0) break;
+ if (scp->refCount == 0)
+ break;
}
if (scp) {
for (tscp = *lscpp;
tscp;
lscpp = &tscp->nextp, tscp = *lscpp) {
- if (tscp == scp) break;
+ if (tscp == scp)
+ break;
}
osi_assertx(tscp, "afsd: scache hash screwup");
*lscpp = scp->nextp;
scp->bulkStatProgress = hzero;
/* discard callback */
+ if (scp->cbServerp) {
+ cm_PutServer(scp->cbServerp);
scp->cbServerp = NULL;
+ }
scp->cbExpires = 0;
/* remove from dnlc */
/* and put it in the LRU queue */
osi_QAdd((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
- if (!cm_scacheLRULastp) cm_scacheLRULastp = scp;
+ if (!cm_scacheLRULastp)
+ cm_scacheLRULastp = scp;
cm_currentSCaches++;
cm_dnlcPurgedp(scp); /* make doubly sure that this is not in dnlc */
cm_dnlcPurgevp(scp);
/* like strcmp, only for fids */
int cm_FidCmp(cm_fid_t *ap, cm_fid_t *bp)
{
- if (ap->vnode != bp->vnode) return 1;
- if (ap->volume != bp->volume) return 1;
- if (ap->unique != bp->unique) return 1;
- if (ap->cell != bp->cell) return 1;
+ if (ap->vnode != bp->vnode)
+ return 1;
+ if (ap->volume != bp->volume)
+ return 1;
+ if (ap->unique != bp->unique)
+ return 1;
+ if (ap->cell != bp->cell)
+ return 1;
return 0;
}
long hash;
cm_scache_t *scp;
long code;
- cm_volume_t *volp;
+ cm_volume_t *volp = 0;
cm_cell_t *cellp;
- char* mp;
+ char* mp = 0;
int special; // yj: boolean variable to test if file is on root.afs
int isRoot;
+ extern cm_fid_t cm_rootFid;
hash = CM_SCACHE_HASH(fidp);
osi_assert(fidp->cell != 0);
+ if (fidp->cell== cm_rootFid.cell &&
+ fidp->volume==cm_rootFid.volume &&
+ fidp->vnode==0x0 && fidp->unique==0x0)
+ {
+ osi_Log0(afsd_logp,"cm_getSCache called with root cell/volume and vnode=0 and unique=0");
+ }
+
// yj: check if we have the scp, if so, we don't need
// to do anything else
lock_ObtainWrite(&cm_scacheLock);
if (cm_freelanceEnabled && isRoot) {
osi_Log0(afsd_logp,"cm_getSCache Freelance and isRoot");
/* freelance: if we are trying to get the root scp for the first
- time, we will just put in a place holder entry. */
+ * time, we will just put in a place holder entry.
+ */
volp = NULL;
}
if (cm_freelanceEnabled && special) {
osi_Log0(afsd_logp,"cm_getSCache Freelance and special");
+ if (fidp->vnode > 1) {
lock_ObtainMutex(&cm_Freelance_Lock);
mp =(cm_localMountPoints+fidp->vnode-2)->mountPointStringp;
lock_ReleaseMutex(&cm_Freelance_Lock);
-
+ } else {
+ mp = "";
+ }
scp = cm_GetNewSCache();
scp->fid = *fidp;
lock_ReleaseWrite(&cm_scacheLock);
/*afsi_log(" getscache done");*/
return 0;
-
}
// end of yj code
#endif /* AFS_FREELANCE_CLIENT */
scp->refCount++;
cm_AdjustLRU(scp);
lock_ReleaseWrite(&cm_scacheLock);
+ if (volp)
cm_PutVolume(volp);
*outScpp = scp;
return 0;
cm_hashTablep[hash] = scp;
scp->flags |= CM_SCACHEFLAG_INHASH;
scp->refCount = 1;
+
+ /* XXX - The following fields in the cm_scache are
+ * uninitialized:
+ * fileType
+ * parentVnode
+ * parentUnique
+ */
lock_ReleaseWrite(&cm_scacheLock);
/* now we have a held scache entry; just return it */
// yj: modified this so that callback only checked if we're
// not checking something on /afs
+ /* fix the conditional to match the one in cm_HaveCallback */
if ( (flags & CM_SCACHESYNC_NEEDCALLBACK)
#ifdef AFS_FREELANCE_CLIENT
- && (!cm_freelanceEnabled || !(!(scp->fid.vnode==0x1 &&
- scp->fid.unique==0x1) &&
- scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
- scp->fid.volume==AFS_FAKE_ROOT_VOL_ID))
+ && (!cm_freelanceEnabled ||
+ !(scp->fid.vnode==0x1 && scp->fid.unique==0x1) ||
+ scp->fid.cell!=AFS_FAKE_ROOT_CELL_ID ||
+ scp->fid.volume!=AFS_FAKE_ROOT_VOL_ID ||
+ cm_fakeDirCallback < 2)
#endif /* AFS_FREELANCE_CLIENT */
) {
if (!cm_HaveCallback(scp)) {
if (bufLocked) lock_ReleaseMutex(&bufp->mx);
osi_SleepM((long) &scp->flags, &scp->mx);
osi_Log0(afsd_logp, "CM SyncOp woke!");
- if (bufLocked) lock_ObtainMutex(&bufp->mx);
+ if (bufLocked)
+ lock_ObtainMutex(&bufp->mx);
lock_ObtainMutex(&scp->mx);
} /* big while loop */
if (cm_freelanceEnabled && scp == cm_rootSCachep) {
osi_Log0(afsd_logp,"cm_MergeStatus Freelance cm_rootSCachep");
statusp->InterfaceVersion = 0x1;
- statusp->FileType = 0x2;
+ statusp->FileType = CM_SCACHETYPE_DIRECTORY;
statusp->LinkCount = scp->linkCount;
statusp->Length = cm_fakeDirSize;
statusp->DataVersion = cm_fakeDirVersion;
else
scp->fileType = CM_SCACHETYPE_SYMLINK;
}
- else scp->fileType = 0; /* invalid */
-
+ else {
+ osi_Log1(afsd_logp, "Merge, Invalid File Type, scp %x", scp);
+ scp->fileType = 0; /* invalid */
+ }
/* and other stuff */
scp->parentVnode = statusp->ParentVnode;
scp->parentUnique = statusp->ParentUnique;
void cm_DiscardSCache(cm_scache_t *scp)
{
lock_AssertMutex(&scp->mx);
+ if (scp->cbServerp) {
+ cm_PutServer(scp->cbServerp);
scp->cbServerp = NULL;
+ }
scp->cbExpires = 0;
cm_dnlcPurgedp(scp);
cm_FreeAllACLEnts(scp);
lock_ObtainWrite(&cm_serverLock);
for(tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
- tsp->refCount++;
+ cm_GetServerNoLock(tsp);
lock_ReleaseWrite(&cm_serverLock);
/* now process the server */
cm_GCConnections(tsp);
lock_ObtainWrite(&cm_serverLock);
- osi_assert(tsp->refCount-- > 0);
+ cm_PutServerNoLock(tsp);
}
lock_ReleaseWrite(&cm_serverLock);
}
}
}
+void cm_GetServer(cm_server_t *serverp)
+{
+ lock_ObtainWrite(&cm_serverLock);
+ serverp->refCount++;
+ afsi_log("cm_GetServer serverp=%x count=%d", serverp, serverp->refCount);
+ lock_ReleaseWrite(&cm_serverLock);
+}
+
+void cm_GetServerNoLock(cm_server_t *serverp)
+{
+ serverp->refCount++;
+ afsi_log("cm_GetServerNoLock serverp=%x count=%d", serverp, serverp->refCount);
+}
+
void cm_PutServer(cm_server_t *serverp)
{
lock_ObtainWrite(&cm_serverLock);
+ afsi_log("cm_PutServer serverp=%x count=%d", serverp, serverp->refCount-1);
osi_assert(serverp->refCount-- > 0);
lock_ReleaseWrite(&cm_serverLock);
}
void cm_PutServerNoLock(cm_server_t *serverp)
{
+ afsi_log("cm_PutServerNoLock serverp=%x count=%d", serverp, serverp->refCount-1);
osi_assert(serverp->refCount-- > 0);
}
serverp->ipRank += min(serverp->ipRank, rand() % 0x000f);
} /* and of for loop */
}
- else serverp->ipRank = 10000 + (rand() % 0x00ff); /* VL server */
+ else
+ serverp->ipRank = 10000 + (rand() % 0x00ff); /* VL server */
}
cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp) {
}
/* bump ref count if we found the server */
- if (tsp) tsp->refCount++;
+ if (tsp)
+ cm_GetServerNoLock(tsp);
/* drop big table lock */
lock_ReleaseWrite(&cm_serverLock);
{
cm_serverRef_t *tsrp;
- lock_ObtainWrite(&cm_serverLock);
- serverp->refCount++;
- lock_ReleaseWrite(&cm_serverLock);
+ cm_GetServer(serverp);
tsrp = malloc(sizeof(*tsrp));
tsrp->server = serverp;
tsrp->status = not_busy;
}
/* call cm_FreeServer while holding a write lock on cm_serverLock */
-void cm_FreeServer(cm_server_t* server)
+void cm_FreeServer(cm_server_t* serverp)
{
- if (--(server->refCount) == 0)
+ cm_PutServerNoLock(serverp);
+ if (serverp->refCount == 0)
{
/* we need to check to ensure that all of the connections
* for this server have a 0 refCount; otherwise, they will
* not be garbage collected
*/
- cm_GCConnections(server); /* connsp */
+ cm_GCConnections(serverp); /* connsp */
- lock_FinalizeMutex(&server->mx);
- if ( cm_allServersp == server )
- cm_allServersp = server->allNextp;
+ lock_FinalizeMutex(&serverp->mx);
+ if ( cm_allServersp == serverp )
+ cm_allServersp = serverp->allNextp;
else {
cm_server_t *tsp;
for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) {
- if ( tsp->allNextp == server ) {
- tsp->allNextp = server->allNextp;
+ if ( tsp->allNextp == serverp ) {
+ tsp->allNextp = serverp->allNextp;
break;
}
}
extern long cm_ChecksumServerList(cm_serverRef_t *serversp);
+extern void cm_GetServer(cm_server_t *);
+
+extern void cm_GetServerNoLock(cm_server_t *);
+
extern void cm_PutServer(cm_server_t *);
extern void cm_PutServerNoLock(cm_server_t *);
psp = tempsp;
tp = psp->data;
cm_ReleaseSCache(tscp);
- tscp = linkScp; /* already held
+ tscp = linkScp;
+ /* already held
* by AssembleLink */
/* now, if linkScp is null, that's
* AssembleLink's way of telling us that
} /* all files in the response */
/* now tell it to drop the count,
* after doing the vnode processing above */
- cm_EndCallbackGrantingCall(NULL, NULL, NULL, 0);
+ cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0);
filex += filesThisCall;
} /* while there are still more files to process */
/* make sure we end things properly */
if (!didEnd)
- cm_EndCallbackGrantingCall(NULL, NULL, NULL, 0);
+ cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0);
return code;
}
/* make sure we end things properly */
if (!didEnd)
- cm_EndCallbackGrantingCall(NULL, NULL, NULL, 0);
+ cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0);
/* and return error code */
return code;
}
/* hold the volume if we found it */
- if (volp) volp->refCount++;
+ if (volp)
+ volp->refCount++;
lock_ReleaseWrite(&cm_volumeLock);
/* return it held */
serverspp = &volp->roServersp;
else if (volume == volp->bkID)
serverspp = &volp->bkServersp;
- else osi_panic("bad volume ID in cm_GetVolServers", __FILE__, __LINE__);
+ else
+ osi_panic("bad volume ID in cm_GetVolServers", __FILE__, __LINE__);
for (current = *serverspp; current; current = current->next)
current->refCount++;
lock_ReleaseWrite(&cm_volumeLock);
/* We should also refresh cached mount points */
-
}
/*
} smb_dirListPatch_t;
/* dirListPatch Flags */
-#define SMB_DIRLISTPATCH_DOTFILE 1 /* the file referenced is a dot file
- Note: will not be set if smb_hideDotFiles is false */
+#define SMB_DIRLISTPATCH_DOTFILE 1
+/* the file referenced is a dot file
+ * Note: will not be set if smb_hideDotFiles is false
+ */
/* waiting lock list elements */
typedef struct smb_waitingLock {
*((u_long *)dptr) = SMB_ATTR_HIDDEN;
}
dptr += 4;
-
} else {
/* 1969-12-31 23:59:58 +00*/
dosTime = 0xEBBFBF7D;
/* merge in hidden (dot file) attribute */
if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) {
- attr == SMB_ATTR_HIDDEN;
+ attr = SMB_ATTR_HIDDEN;
*dptr++ = attr & 0xff;
*dptr++ = (attr >> 8) & 0xff;
}
-
}
continue;
}
{
static char lastcell[MAXCELLCHARS+1] = { 0 };
static char confname[512] = { 0 };
+ char username_copy[BUFSIZ];
long viceId; /* AFS uid of user */
#ifdef ALLOW_REGISTER
afs_int32 id;
#else /* ALLOW_REGISTER */
if ((*status == 0) && (viceId != ANONYMOUSID))
#endif /* ALLOW_REGISTER */
- sprintf (username, "AFS ID %d", (int) viceId);
+ {
+#ifdef AFS_ID_TO_NAME
+ strncpy(username_copy, username, BUFSIZ);
+ snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
+#endif /* AFS_ID_TO_NAME */
+ }
#ifdef ALLOW_REGISTER
} else if (strcmp(realm_of_user, realm_of_cell) != 0) {
if (dflag) {
printf("%s: unable to obtain tokens for cell %s "
"(status: %d).\n", progname, cell_to_use, status);
*status = AKLOG_TOKEN;
+ return ;
}
/*
if ((*status = pr_Initialize(1L, confname, aserver->cell, 0))) {
printf("Error %d\n", status);
+ return;
}
if ((*status = pr_CreateUser(username, &id))) {
} else {
printf("created cross-cell entry for %s at %s\n",
username, cell_to_use);
- sprintf(username, "AFS ID %d", (int) id);
+#ifdef AFS_ID_TO_NAME
+ strncpy(username_copy, username, BUFSIZ);
+ snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
+#endif /* AFS_ID_TO_NAME */
}
}
}
*s++ = c;
}
*s++ = 0;
-
}
return krbrlm;
}
memcpy(&atoken.sessionKey, v5cred->keyblock.contents, v5cred->keyblock.length);
atoken.ticketLen = v5cred->ticket.length;
memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
- } else
- {
+ } else {
strcpy (username, c.pname);
if (c.pinst[0])
{
progname, status);
return(AKLOG_KERBEROS);
}
- } else
- {
+ } else {
if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS)
{
fprintf(stderr, "%s: Couldn't determine realm of user: %s)",
*/
strncpy(aclient.name, username, MAXKTCNAMELEN - 1);
strcpy(aclient.instance, "");
+
if (usev5) {
int len = min(v5cred->client->realm.length,MAXKTCNAMELEN - 1);
strncpy(aclient.cell, v5cred->client->realm.data, len);
for (cur_node = cells.first; cur_node; cur_node = cur_node->next)
{
memcpy(&cellinfo, cur_node->data, sizeof(cellinfo));
- if (status = auth_to_cell(
- context,
+ if (status = auth_to_cell(context,
cellinfo.cell, cellinfo.realm))
somethingswrong++;
}
/* Then, log to all paths in the paths list */
for (cur_node = paths.first; cur_node; cur_node = cur_node->next)
{
- if (status = auth_to_path(
- context,
+ if (status = auth_to_path(context,
cur_node->data))
somethingswrong++;
}
if (b == 0) { return result; }
if (b == 1) { *remainder = 0; return a; }
- a1=(a.HighPart << 32) | a.LowPart;
+ a1 = a.HighPart;
+ a1 <<= 32;
+ a1 |= a.LowPart;
q1=a1/b;
r1=a1-(q1*b);
if (r1 > ULONG_MAX) /*XXX */;
return a;
}
- a1=(a.HighPart << 32) | a.LowPart;
- b1=(b.HighPart << 32) | a.LowPart;
+ a1 = a.HighPart;
+ a1 <<= 32;
+ a1 |= a.LowPart;
+ b1 = b.HighPart;
+ b1 <<= 32;
+ b1 |= b.LowPart;
q1=a1/b1;
r1=a1-(q1*b1);
result.HighPart=q1 >> 32;
#define used in WinNT/2000 installation and program version display
AFSPRODUCT_VER_MAJOR=1
AFSPRODUCT_VER_MINOR=3
-AFSPRODUCT_VER_PATCH=7000
+AFSPRODUCT_VER_PATCH=7001
AFSPRODUCT_VER_BUILD=0
AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
AFSPRODUCT_FILE_VERSION=$(AFSPRODUCT_VER_MAJOR),$(AFSPRODUCT_VER_MINOR),$(AFSPRODUCT_VER_PATCH),$(AFSPRODUCT_VER_BUILD)
!IF ("$(AFSVER_CL)"!="1200")
afscdefs = $(afscdefs) /GT /GS
+#/Wp64
!IF ("$(AFSVER_CL)"!="1400")
afscdefs = $(afscdefs) /G7
!ENDIF
SyncVldb(as)
register struct cmd_syndesc *as;
{
- afs_int32 pnum, code; /* part name */
+ afs_int32 pnum = 0, code; /* part name */
char part[10];
int flags = 0;
char *volname = 0;