From 09feb1be1711dbbe053b572915df4384f488eb0e Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 31 Jan 2005 18:52:30 +0000 Subject: [PATCH] windows-misc-20050131 afskfw.c: fix cross-realm token acquisition in ANDREW vs CS CMU case cm_aclent.c: when ACL's timeout, remove them from the associated cm_scache_t object's randomACL list and place them on the end of the ACL LRU queue correct tgtLifetime to be unsigned smb3.c: fix case sensitive matching --- src/WINNT/afsd/afskfw.c | 30 ++++++++++----- src/WINNT/afsd/cm_aclent.c | 76 ++++++++++++++++++++++---------------- src/WINNT/afsd/cm_aclent.h | 2 +- src/WINNT/afsd/smb3.c | 23 +++++++----- 4 files changed, 80 insertions(+), 51 deletions(-) diff --git a/src/WINNT/afsd/afskfw.c b/src/WINNT/afsd/afskfw.c index 2f3b6408e..c57dcb70e 100644 --- a/src/WINNT/afsd/afskfw.c +++ b/src/WINNT/afsd/afskfw.c @@ -1166,8 +1166,7 @@ KFW_AFS_get_cred( char * username, { krb5_context ctx = 0; krb5_ccache cc = 0; - char * realm = 0; - char ** realmlist = 0; + char * realm = 0, * userrealm = 0; krb5_principal principal = 0; char * pname = 0; krb5_error_code code; @@ -1195,19 +1194,19 @@ KFW_AFS_get_cred( char * username, code = KFW_AFS_get_cellconfig( cell, (void*)&cellconfig, local_cell); if ( code ) goto cleanup; - realm = strchr(username,'@'); - if ( realm ) { + realm = afs_realm_of_cell(ctx, &cellconfig); // do not free + userrealm = strchr(username,'@'); + if (userrealm) { pname = strdup(username); - realm = strchr(pname, '@'); - *realm = '\0'; + userrealm = strchr(pname, '@'); + *userrealm = '\0'; /* handle kerberos iv notation */ while ( dot = strchr(pname,'.') ) { *dot = '/'; } - *realm++ = '@'; + *userrealm++ = '@'; } else { - realm = afs_realm_of_cell(ctx, &cellconfig); // do not free pname = malloc(strlen(username) + strlen(realm) + 2); strcpy(pname, username); @@ -2430,7 +2429,9 @@ ViceIDToUsername(char *username, { static char lastcell[MAXCELLCHARS+1] = { 0 }; static char confname[512] = { 0 }; +#ifdef AFS_ID_TO_NAME char username_copy[BUFSIZ]; +#endif /* AFS_ID_TO_NAME */ long viceId; /* AFS uid of user */ int status = 0; #ifdef ALLOW_REGISTER @@ -2538,7 +2539,9 @@ KFW_AFS_klog( { long rc = 0; CREDENTIALS creds; +#ifdef USE_KRB4 KTEXT_ST ticket; +#endif /* USE_KRB4 */ struct ktc_principal aserver; struct ktc_principal aclient; char realm_of_user[REALM_SZ]; /* Kerberos realm of user */ @@ -2560,6 +2563,7 @@ KFW_AFS_klog( krb5_creds * k5creds = 0; krb5_error_code code; krb5_principal client_principal = 0; + krb5_data * k5data; int i, retry = 0; CurrentState = 0; @@ -2621,7 +2625,15 @@ KFW_AFS_klog( goto skip_krb5_init; } - if ( strchr(krb5_princ_component(ctx,client_principal,0),'.') != NULL ) + /* lookfor client principals which cannot be distinguished + * from Kerberos 4 multi-component principal names + */ + k5data = krb5_princ_component(ctx,client_principal,0); + for ( i=0; ilength; i++ ) { + if ( k5data->data[i] == '.' ) + break; + } + if (i != k5data->length) { OutputDebugString("Illegal Principal name contains dot in first component\n"); rc = KRB5KRB_ERR_GENERIC; diff --git a/src/WINNT/afsd/cm_aclent.c b/src/WINNT/afsd/cm_aclent.c index 89902dc74..44e623cbd 100644 --- a/src/WINNT/afsd/cm_aclent.c +++ b/src/WINNT/afsd/cm_aclent.c @@ -24,12 +24,44 @@ * in either the free list or in the LRU queue. A read lock prevents someone * from modifying the list(s), and a write lock is required for modifying * the list. The actual data stored in the randomUid and randomAccess fields - * is actually maintained as up-to-date or not via the scache llock. + * is actually maintained as up-to-date or not via the scache lock. * An aclent structure is free if it has no back vnode pointer. */ osi_rwlock_t cm_aclLock; /* lock for system's aclents */ cm_aclent_t *cm_aclLRUp; /* LRUQ for dudes in vnode's lists */ cm_aclent_t *cm_aclLRUEndp; /* ditto */ + +/* This function must be called with cm_aclLock and the aclp->back_mx held */ +static void CleanupACLEnt(cm_aclent_t * aclp) +{ + cm_aclent_t *taclp; + cm_aclent_t **laclpp; + + if (aclp->backp) { + /* + * Remove the entry from the vnode's list + */ + laclpp = &aclp->backp->randomACLp; + for ( taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp ) { + if (taclp == aclp) + break; + } + if (!taclp) + osi_panic("CleanupACLEnt race",__FILE__,__LINE__); + *laclpp = aclp->nextp; /* remove from the vnode's list */ + aclp->backp = NULL; + } + + /* release the old user */ + if (aclp->userp) { + cm_ReleaseUser(aclp->userp); + aclp->userp = NULL; + } + + aclp->randomAccess = 0; + aclp->tgtLifetime = 0; +} + /* * Get an acl cache entry for a particular user and file, or return that it doesn't exist. * Called with the scp locked. @@ -40,16 +72,18 @@ long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, long *rightsp) long retval = -1; lock_ObtainWrite(&cm_aclLock); + *rightsp = 0; /* get a new acl from server if we don't find a + * current entry + */ for (aclp = scp->randomACLp; aclp; aclp = aclp->nextp) { if (aclp->userp == userp) { - if (aclp->tgtLifetime && aclp->tgtLifetime <= (long) osi_Time()) { + if (aclp->tgtLifetime && aclp->tgtLifetime <= osi_Time()) { /* ticket expired */ - aclp->tgtLifetime = 0; - *rightsp = 0; /* get a new acl from server */ - - /* Shouldn't we remove this entry from the scp? - * 2005-01-25 - jaltman@secure-endpoints.com - */ + osi_QRemove((osi_queue_t **) &cm_aclLRUp, &aclp->q); + CleanupACLEnt(aclp); + osi_QAddT((osi_queue_t **) &cm_aclLRUp, + (osi_queue_t **) &cm_aclLRUEndp, + &aclp->q); } else { *rightsp = aclp->randomAccess; if (cm_aclLRUEndp == aclp) @@ -78,36 +112,14 @@ long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, long *rightsp) static cm_aclent_t *GetFreeACLEnt(void) { cm_aclent_t *aclp; - cm_aclent_t *taclp; - cm_aclent_t **laclpp; if (cm_aclLRUp == NULL) osi_panic("empty aclent LRU", __FILE__, __LINE__); aclp = cm_aclLRUEndp; - if (aclp == cm_aclLRUEndp) - cm_aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q); + cm_aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q); osi_QRemove((osi_queue_t **) &cm_aclLRUp, &aclp->q); - if (aclp->backp) { - /* - * Remove the entry from the vnode's list - */ - laclpp = &aclp->backp->randomACLp; - for (taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp) { - if (taclp == aclp) - break; - } - if (!taclp) - osi_panic("GetFreeACLEnt race", __FILE__, __LINE__); - *laclpp = aclp->nextp; /* remove from vnode list */ - aclp->backp = NULL; - } - - /* release the old user */ - if (aclp->userp) { - cm_ReleaseUser(aclp->userp); - aclp->userp = NULL; - } + CleanupACLEnt(aclp); return aclp; } diff --git a/src/WINNT/afsd/cm_aclent.h b/src/WINNT/afsd/cm_aclent.h index 2e2a63f3e..f24ee67d4 100644 --- a/src/WINNT/afsd/cm_aclent.h +++ b/src/WINNT/afsd/cm_aclent.h @@ -23,7 +23,7 @@ typedef struct cm_aclent { struct cm_scache *backp; /* back ptr to vnode */ struct cm_user *userp; /* user whose access is cached */ long randomAccess; /* watch for more rights in acl.h */ - long tgtLifetime; /* time this expires */ + unsigned long tgtLifetime; /* time this expires */ } cm_aclent_t; extern osi_rwlock_t cm_aclLock; diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 73844a4dd..520dddb38 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -3362,7 +3362,7 @@ VOID initUpperCaseTable(VOID) // BOOL : TRUE/FALSE (match/mistmatch) BOOL -szWildCardMatchFileName(PSZ pattern, PSZ name) +szWildCardMatchFileName(PSZ pattern, PSZ name, int casefold) { PSZ pename; // points to the last 'name' character PSZ p; @@ -3379,13 +3379,15 @@ szWildCardMatchFileName(PSZ pattern, PSZ name) if (*pattern == '\0') return TRUE; for (p = pename; p >= name; --p) { - if ((mapCaseTable[*p] == mapCaseTable[*pattern]) && - szWildCardMatchFileName(pattern + 1, p + 1)) + if ((casefold && (mapCaseTable[*p] == mapCaseTable[*pattern]) || + !casefold && (*p == *pattern)) && + szWildCardMatchFileName(pattern + 1, p + 1, casefold)) return TRUE; } /* endfor */ return FALSE; default: - if (mapCaseTable[*name] != mapCaseTable[*pattern]) + if ((casefold && mapCaseTable[*name] != mapCaseTable[*pattern]) || + (!casefold && *name != *pattern)) return FALSE; ++pattern, ++name; break; @@ -3404,12 +3406,14 @@ szWildCardMatchFileName(PSZ pattern, PSZ name) int smb_V3MatchMask(char *namep, char *maskp, int flags) { char * newmask; - int i, j, star, qmark, retval; + int i, j, star, qmark, casefold, retval; /* make sure we only match 8.3 names, if requested */ if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) return 0; + casefold = (flags & CM_FLAG_CASEFOLD) ? 1 : 0; + /* optimize the pattern: * if there is a mixture of '?' and '*', * for example the sequence "*?*?*?*" @@ -3446,7 +3450,7 @@ int smb_V3MatchMask(char *namep, char *maskp, int flags) } newmask[j++] = '\0'; - retval = szWildCardMatchFileName(newmask, namep) ? 1:0; + retval = szWildCardMatchFileName(newmask, namep, casefold) ? 1:0; free(newmask); return retval; @@ -5407,8 +5411,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } if (scp->fileType != CM_SCACHETYPE_FILE) { - if (dscp) - cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); @@ -5419,7 +5423,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* (only applies to single component case) */ if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) { cm_ReleaseSCache(scp); - cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_NOTDIR; -- 2.39.5