windows-misc-20050131
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 31 Jan 2005 18:52:30 +0000 (18:52 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 31 Jan 2005 18:52:30 +0000 (18:52 +0000)
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
src/WINNT/afsd/cm_aclent.c
src/WINNT/afsd/cm_aclent.h
src/WINNT/afsd/smb3.c

index 2f3b640..c57dcb7 100644 (file)
@@ -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; i<k5data->length; i++ ) {
+        if ( k5data->data[i] == '.' )
+            break;
+    }
+    if (i != k5data->length)
     {
         OutputDebugString("Illegal Principal name contains dot in first component\n");
         rc = KRB5KRB_ERR_GENERIC;
index 89902dc..44e623c 100644 (file)
  * 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;
 }
 
index 2e2a63f..f24ee67 100644 (file)
@@ -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;
index 73844a4..520dddb 100644 (file)
@@ -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;