Пример #1
0
BOOL fIsCellInCellServDB (LPCTSTR pszCell)
{
   BOOL fFound = FALSE;
   CELLSERVDB CellServDB;
   char cellname[256], i;

   /* we pray for all ascii cellnames */
   for ( i=0 ; pszCell[i] && i < (sizeof(cellname)-1) ; i++ )
       cellname[i] = pszCell[i];
   cellname[i] = '\0';

   ULONG code = cm_SearchCellRegistry(1, cellname, NULL, NULL, NULL, NULL);
   if (code == 0)
      fFound = TRUE;
   if (!fFound && 
       (code != CM_ERROR_FORCE_DNS_LOOKUP) && 
       CSDB_ReadFile (&CellServDB, NULL))
   {
       if (CSDB_FindCell (&CellServDB, pszCell))
           fFound = TRUE;
       CSDB_FreeFile (&CellServDB);
   }
   if ( fFound == FALSE ) {
       int ttl;
       fFound = !cm_SearchCellByDNS(cellname, NULL, &ttl, NULL, NULL);
   }
   done:

   return fFound;
}
Пример #2
0
BOOL fIsCellInCellServDB (LPCTSTR pszCell)
{
   BOOL fFound = FALSE;
   CELLSERVDB CellServDB;

   if (CSDB_ReadFile (&CellServDB, NULL))
   {
       if (CSDB_FindCell (&CellServDB, pszCell))
           fFound = TRUE;
       CSDB_FreeFile (&CellServDB);
   }
#ifdef AFS_AFSDB_ENV
    if ( fFound == FALSE ) {
        int ttl;
        char cellname[128], i;

        /* we pray for all ascii cellnames */
        for ( i=0 ; pszCell[i] && i < (sizeof(cellname)-1) ; i++ )
            cellname[i] = pszCell[i];
        cellname[i] = '\0';

        fFound = !cm_SearchCellByDNS(cellname, NULL, &ttl, NULL, NULL);
    }
#endif
   return fFound;
}
Пример #3
0
BOOL HostsTab_OnApply (HWND hDlg)
{
   // Don't try to do anything if we've already failed the apply
   if (GetWindowLongPtr (hDlg, DWLP_MSGRESULT))
      return FALSE;

   if (!CSDB_WriteFile (&g.Configuration.CellServDB))
      return FALSE;

   // If this is the Control Center applet, we'll have to validate
   // the cell name too.
   //
   if (g.fIsCCenter)
      {
      TCHAR szNoCell[ cchRESOURCE ];
      GetString (szNoCell, IDS_CELL_UNKNOWN);

      TCHAR szCell[ cchRESOURCE ];
      GetDlgItemText (hDlg, IDC_CELL, szCell, cchRESOURCE);

      if ((!szCell[0]) || (!lstrcmpi (szNoCell, szCell)))
         {
         Message (MB_ICONASTERISK | MB_OK, GetErrorTitle(), IDS_NOCELL_DESC_CC);
         return FALSE;
         }

      char cellname[256], i;

      /* we pray for all ascii cellnames */
      for ( i=0 ; szCell[i] && i < (sizeof(cellname)-1) ; i++ )
          cellname[i] = szCell[i];
      cellname[i] = '\0';

      ULONG code = cm_SearchCellRegistry(1, cellname, NULL, NULL, NULL, NULL);
      if (code && 
          code != CM_ERROR_FORCE_DNS_LOOKUP &&
          !CSDB_FindCell (&g.Configuration.CellServDB, szCell))
         {
             int ttl;
             if (cm_SearchCellByDNS(cellname, NULL, &ttl, NULL, NULL))
             {
                 Message (MB_ICONASTERISK | MB_OK, GetErrorTitle(), IDS_BADCELL_DESC_CC);
                 return FALSE;
             }
         }

      if (!Config_SetCellName (szCell))
         return FALSE;
      lstrcpy (g.Configuration.szCell, szCell);
      }

   return TRUE;
}
Пример #4
0
static long
cm_enumCellRegistryProc(void *rockp, char * cellNamep)
{
    long code;
    cm_enumCellRegistry_t *enump = (cm_enumCellRegistry_t *)rockp;
    char linkedName[256] = "";
    int timeout = 0;
    struct afsconf_entry *newEntry;


    newEntry = malloc(sizeof(struct afsconf_entry));
    if (newEntry == NULL)
        return ENOMEM;
    newEntry->cellInfo.numServers = 0;

    code = cm_SearchCellRegistry(enump->client, cellNamep, NULL, linkedName, cm_serverConfigProc, &newEntry->cellInfo);
    if (code == CM_ERROR_FORCE_DNS_LOOKUP)
        code = cm_SearchCellByDNS(cellNamep, NULL, &timeout, cm_serverConfigProc, &newEntry->cellInfo);

    if (code == 0) {
        strncpy(newEntry->cellInfo.name, cellNamep, MAXCELLCHARS);
        newEntry->cellInfo.name[MAXCELLCHARS-1];
        if (linkedName[0])
            newEntry->cellInfo.linkedCell = strdup(linkedName);
        else
            newEntry->cellInfo.linkedCell = NULL;
        newEntry->cellInfo.timeout = timeout;
        newEntry->cellInfo.flags = 0;

        newEntry->next = enump->adir->entries;
	enump->adir->entries = newEntry;
    } else {
        free(newEntry);
    }
    return code;
}
Пример #5
0
/* if it's from DNS, see if it has expired
 * and check to make sure we have a valid set of volume servers
 * this function must not be called with a lock on cm_cellLock
 */
cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags)
{
    long code = 0;
    cm_cell_rock_t rock;
    afs_uint32 mxheld = 0;

    if (cp == NULL)
        return NULL;

    lock_ObtainMutex(&cp->mx);
    mxheld = 1;

#ifdef AFS_FREELANCE_CLIENT
    if (cp->flags & CM_CELLFLAG_FREELANCE) {
        lock_ReleaseMutex(&cp->mx);
        return cp;
    }
#endif

    if (cm_IsServerListEmpty(cp->vlServersp) ||
        (time(0) > cp->timeout) ||
        (cm_dnsEnabled &&
         (cp->flags & CM_CELLFLAG_DNS) &&
         ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID))))
    {
        lock_ReleaseMutex(&cp->mx);
        mxheld = 0;

        /* must empty cp->vlServersp */
        if (cp->vlServersp)
            cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE);

        rock.cellp = cp;
        rock.flags = flags;
        code = cm_SearchCellRegistry(1, cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
        if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
            code = cm_SearchCellFileEx(cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
        if (code == 0) {
            lock_ObtainMutex(&cp->mx);
            mxheld = 1;
	    cp->timeout = time(0) + 7200;
        }
        else {
            if (cm_dnsEnabled) {
                int ttl;

                code = cm_SearchCellByDNS(cp->name, NULL, &ttl, cm_AddCellProc, &rock);
                if (code == 0) {   /* got cell from DNS */
                    lock_ObtainMutex(&cp->mx);
                    mxheld = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_DNS);
                    _InterlockedAnd(&cp->flags, ~CM_CELLFLAG_VLSERVER_INVALID);
		    cp->timeout = time(0) + ttl;
#ifdef DEBUG
                    fprintf(stderr, "cell %s: ttl=%d\n", cp->name, ttl);
#endif
		} else {
                    /* if we fail to find it this time, we'll just do nothing and leave the
                     * current entry alone
		     */
                    lock_ObtainMutex(&cp->mx);
                    mxheld = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_VLSERVER_INVALID);
                }
	    }
	}
    }

    if (code == 0)
        cm_RandomizeServer(&cp->vlServersp);

    if (mxheld)
        lock_ReleaseMutex(&cp->mx);

    return code ? NULL : cp;
}
Пример #6
0
long
cm_CreateCellWithInfo( char * cellname,
                       char * linked_cellname,
                       unsigned short vlport,
                       afs_uint32 host_count,
                       char *hostname[],
                       afs_uint32 flags)
{
    afs_uint32 code = 0;
    cm_cell_rock_t rock;
    struct hostent *thp;
    struct sockaddr_in vlSockAddr;
    afs_uint32 i, j;

    rock.cellp = cm_GetCell(cellname, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
    rock.flags = 0;

    cm_FreeServerList(&rock.cellp->vlServersp, CM_FREESERVERLIST_DELETE);

    if (!(flags & CM_CELLFLAG_DNS)) {
        for (i = 0; i < host_count; i++) {
            thp = gethostbyname(hostname[i]);
            if (thp) {
                int foundAddr = 0;
                for (j=0 ; thp->h_addr_list[j]; j++) {
                    if (thp->h_addrtype != AF_INET)
                        continue;
                    memcpy(&vlSockAddr.sin_addr.s_addr,
                           thp->h_addr_list[j],
                           sizeof(long));
                    vlSockAddr.sin_port = htons(vlport ? vlport : 7003);
                    vlSockAddr.sin_family = AF_INET;
                    cm_AddCellProc(&rock, &vlSockAddr, hostname[i], CM_FLAG_NOPROBE);
                }
            }
        }
        lock_ObtainMutex(&rock.cellp->mx);
        _InterlockedAnd(&rock.cellp->flags, ~CM_CELLFLAG_DNS);
    } else if (cm_dnsEnabled) {
        int ttl;

        code = cm_SearchCellByDNS(rock.cellp->name, NULL, &ttl, cm_AddCellProc, &rock);
        lock_ObtainMutex(&rock.cellp->mx);
        if (code == 0) {   /* got cell from DNS */
            _InterlockedOr(&rock.cellp->flags, CM_CELLFLAG_DNS);
            rock.cellp->timeout = time(0) + ttl;
#ifdef DEBUG
            fprintf(stderr, "cell %s: ttl=%d\n", rock.cellp->name, ttl);
#endif
        }
    } else {
        lock_ObtainMutex(&rock.cellp->mx);
        rock.cellp->flags &= ~CM_CELLFLAG_DNS;
    }
    _InterlockedOr(&rock.cellp->flags, CM_CELLFLAG_VLSERVER_INVALID);
    StringCbCopy(rock.cellp->linkedName, CELL_MAXNAMELEN, linked_cellname);
    lock_ReleaseMutex(&rock.cellp->mx);

    if (rock.cellp->vlServersp)
        cm_RandomizeServer(&rock.cellp->vlServersp);

    return code;
}
Пример #7
0
cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
{
    cm_cell_t *cp, *cp2;
    long code;
    char fullname[CELL_MAXNAMELEN]="";
    char linkedName[CELL_MAXNAMELEN]="";
    char name[CELL_MAXNAMELEN]="";
    int  hasWriteLock = 0;
    int  hasMutex = 0;
    afs_uint32 hash;
    cm_cell_rock_t rock;
    size_t len;

    if (namep == NULL || !namep[0] || !strcmp(namep,CM_IOCTL_FILENAME_NOSLASH))
        return NULL;

    /*
     * Strip off any trailing dots at the end of the cell name.
     * Failure to do so results in an undesireable alias as the
     * result of DNS AFSDB record lookups where a trailing dot
     * has special meaning.
     */
    strncpy(name, namep, CELL_MAXNAMELEN);
    for (len = strlen(namep); len > 0 && namep[len-1] == '.'; len--) {
        name[len-1] = '\0';
    }
    if (len == 0)
        return NULL;
    namep = name;

    hash = CM_CELL_NAME_HASH(namep);

    lock_ObtainRead(&cm_cellLock);
    for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) {
        if (cm_stricmp_utf8(namep, cp->name) == 0) {
            strncpy(fullname, cp->name, CELL_MAXNAMELEN);
            fullname[CELL_MAXNAMELEN-1] = '\0';
            break;
        }
    }

    if (!cp) {
        for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) {
            if (strnicmp(namep, cp->name, strlen(namep)) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }
    }

    if (cp) {
        lock_ReleaseRead(&cm_cellLock);
        cm_UpdateCell(cp, flags);
    } else if (flags & CM_FLAG_CREATE) {
        lock_ConvertRToW(&cm_cellLock);
        hasWriteLock = 1;

        /* when we dropped the lock the cell could have been added
         * to the list so check again while holding the write lock
         */
        for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) {
            if (cm_stricmp_utf8(namep, cp->name) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }

        if (cp)
            goto done;

        for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) {
            if (strnicmp(namep, cp->name, strlen(namep)) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }

        if (cp) {
            lock_ReleaseWrite(&cm_cellLock);
            lock_ObtainMutex(&cp->mx);
            lock_ObtainWrite(&cm_cellLock);
            cm_AddCellToNameHashTable(cp);
            cm_AddCellToIDHashTable(cp);
            lock_ReleaseMutex(&cp->mx);
            goto done;
        }

        if ( cm_data.freeCellsp != NULL ) {
            cp = cm_data.freeCellsp;
            cm_data.freeCellsp = cp->freeNextp;

            /*
             * The magic, cellID, and mx fields are already set.
             */
        } else {
            if ( cm_data.currentCells >= cm_data.maxCells )
                osi_panic("Exceeded Max Cells", __FILE__, __LINE__);

            /* don't increment currentCells until we know that we
             * are going to keep this entry
             */
            cp = &cm_data.cellBaseAddress[cm_data.currentCells];
            memset(cp, 0, sizeof(cm_cell_t));
            cp->magic = CM_CELL_MAGIC;

            /* the cellID cannot be 0 */
            cp->cellID = ++cm_data.currentCells;

            /* otherwise we found the cell, and so we're nearly done */
            lock_InitializeMutex(&cp->mx, "cm_cell_t mutex", LOCK_HIERARCHY_CELL);
        }

        lock_ReleaseWrite(&cm_cellLock);
        hasWriteLock = 0;

        rock.cellp = cp;
        rock.flags = flags;
        code = cm_SearchCellRegistry(1, namep, fullname, linkedName, cm_AddCellProc, &rock);
        if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
            code = cm_SearchCellFileEx(namep, fullname, linkedName, cm_AddCellProc, &rock);
        if (code) {
            osi_Log4(afsd_logp,"in cm_GetCell_gen cm_SearchCellFileEx(%s) returns code= %d fullname= %s linkedName= %s",
                      osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname),
                      osi_LogSaveString(afsd_logp,linkedName));

            if (cm_dnsEnabled) {
                int ttl;

                code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, &rock);
                if ( code ) {
                    osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
                             osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname));
                    lock_ObtainMutex(&cp->mx);
                    lock_ObtainWrite(&cm_cellLock);
                    hasWriteLock = 1;
                    cm_RemoveCellFromIDHashTable(cp);
                    cm_RemoveCellFromNameHashTable(cp);
                    lock_ReleaseMutex(&cp->mx);
                    cm_FreeCell(cp);
                    cp = NULL;
                    goto done;
                } else {   /* got cell from DNS */
                    lock_ObtainMutex(&cp->mx);
                    hasMutex = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_DNS);
                    _InterlockedAnd(&cp->flags, ~CM_CELLFLAG_VLSERVER_INVALID);
                    cp->timeout = time(0) + ttl;
                }
            }
            else
            {
                lock_ObtainMutex(&cp->mx);
                lock_ObtainWrite(&cm_cellLock);
                hasWriteLock = 1;
                cm_RemoveCellFromIDHashTable(cp);
                cm_RemoveCellFromNameHashTable(cp);
                lock_ReleaseMutex(&cp->mx);
                cm_FreeCell(cp);
                cp = NULL;
                goto done;
	    }
        } else {
            lock_ObtainMutex(&cp->mx);
            hasMutex = 1;
	    cp->timeout = time(0) + 7200;	/* two hour timeout */
	}

        /* we have now been given the fullname of the cell.  It may
         * be that we already have a cell with that name.  If so,
         * we should use it instead of completing the allocation
         * of a new cm_cell_t
         */
        lock_ObtainRead(&cm_cellLock);
        hash = CM_CELL_NAME_HASH(fullname);
        for (cp2 = cm_data.cellNameHashTablep[hash]; cp2; cp2=cp2->nameNextp) {
            if (cm_stricmp_utf8(fullname, cp2->name) == 0) {
                break;
            }
        }

        if (cp2) {
            if (!hasMutex) {
                lock_ObtainMutex(&cp->mx);
                hasMutex = 1;
            }
            lock_ConvertRToW(&cm_cellLock);
            hasWriteLock = 1;
            cm_RemoveCellFromIDHashTable(cp);
            cm_RemoveCellFromNameHashTable(cp);
            lock_ReleaseMutex(&cp->mx);
            hasMutex = 0;
            cm_FreeCell(cp);
            cp = cp2;
            goto done;
        }
        lock_ReleaseRead(&cm_cellLock);

        /* randomise among those vlservers having the same rank*/
        cm_RandomizeServer(&cp->vlServersp);

        if (!hasMutex)
            lock_ObtainMutex(&cp->mx);

        /* copy in name */
        strncpy(cp->name, fullname, CELL_MAXNAMELEN);
        cp->name[CELL_MAXNAMELEN-1] = '\0';

        strncpy(cp->linkedName, linkedName, CELL_MAXNAMELEN);
        cp->linkedName[CELL_MAXNAMELEN-1] = '\0';

        lock_ObtainWrite(&cm_cellLock);
        hasWriteLock = 1;
        cm_AddCellToNameHashTable(cp);
        cm_AddCellToIDHashTable(cp);
        lock_ReleaseMutex(&cp->mx);
        hasMutex = 0;

        /* append cell to global list */
        if (cm_data.allCellsp == NULL) {
            cm_data.allCellsp = cp;
        } else {
            for (cp2 = cm_data.allCellsp; cp2->allNextp; cp2=cp2->allNextp)
                ;
            cp2->allNextp = cp;
        }
        cp->allNextp = NULL;

    } else {
        lock_ReleaseRead(&cm_cellLock);
    }
  done:
    if (hasMutex && cp)
        lock_ReleaseMutex(&cp->mx);
    if (hasWriteLock)
        lock_ReleaseWrite(&cm_cellLock);

    /* fullname is not valid if cp == NULL */
    if (newnamep) {
        if (cp) {
            strncpy(newnamep, fullname, CELL_MAXNAMELEN);
            newnamep[CELL_MAXNAMELEN-1]='\0';
        } else {
            newnamep[0] = '\0';
        }
    }

    if (cp && cp->linkedName[0]) {
        cm_cell_t * linkedCellp = NULL;

        if (!strcmp(cp->name, cp->linkedName)) {
            cp->linkedName[0] = '\0';
        } else if (!(flags & CM_FLAG_NOMOUNTCHASE)) {
            linkedCellp = cm_GetCell(cp->linkedName, CM_FLAG_CREATE|CM_FLAG_NOPROBE|CM_FLAG_NOMOUNTCHASE);

            lock_ObtainWrite(&cm_cellLock);
            if (!linkedCellp ||
                (linkedCellp->linkedName[0] && strcmp(cp->name, linkedCellp->linkedName))) {
                cp->linkedName[0] = '\0';
            } else {
                strncpy(linkedCellp->linkedName, cp->name, CELL_MAXNAMELEN);
                linkedCellp->linkedName[CELL_MAXNAMELEN-1]='\0';
            }
            lock_ReleaseWrite(&cm_cellLock);
        }
    }
    return cp;
}
Пример #8
0
afs_int32
ka_UserAuthenticateGeneral2(afs_int32 flags, char *name, char *instance,
			    char *realm, char *password, char *smbname,
			    Date lifetime, afs_int32 * password_expiresP,
			    afs_int32 spare, char **reasonP)
{
    int code;
    struct ktc_encryptionKey key1, key2;
    char *ticket = NULL;
    int ticketLen;
    struct ktc_encryptionKey sessionKey;
    long kvno;
    long expirationTime;
    char fullRealm[256];
    char upperRealm[256];
    struct servent *sp;
    int ttl;

    struct ktc_principal server;
    struct ktc_principal client;
    struct ktc_token token;

    if (instance == NULL)
	instance = "";
    if (lifetime == 0)
	lifetime = MAXKTCTICKETLIFETIME;

    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);
    }

    strcpy(upperRealm, fullRealm);
    _strupr(upperRealm);

    /* encrypt password, both ways */
    ka_StringToKey(password, upperRealm, &key1);
    des_string_to_key(password, &key2);

    /* set port number */
    sp = getservbyname("kerberos", "udp");
    if (sp)
	krb_set_port(ntohs(sp->s_port));

    *reasonP = NULL;
    code =
	krb_get_in_tkt_ext(name, instance, upperRealm, "afs", "", lifetime,
			   &key1, &key2, &ticket, &ticketLen, &sessionKey,
			   &kvno, &expirationTime, reasonP);

    if (code && *reasonP == NULL)
	*reasonP = ka_MapKerberosError(code);

    if (code)
	return code;

    strcpy(server.name, "afs");
    strcpy(server.instance, "");
    strcpy(server.cell, fullRealm);

    /* Would like to use Vice ID's; using raw names for now. */
    strcpy(client.name, name);
    strcpy(client.instance, instance);
    strcpy(client.cell, upperRealm);
    if (smbname)
	strcpy(client.smbname, smbname);

    token.startTime = 0;	/* XXX */
    token.endTime = expirationTime;
    token.sessionKey = sessionKey;
    token.kvno = (short)kvno;
    token.ticketLen = ticketLen;
    memcpy(token.ticket, ticket, ticketLen);

    code =
	ktc_SetToken(&server, &token, &client,
		     (flags & KA_USERAUTH_AUTHENT_LOGON) ? AFS_SETTOK_LOGON :
		     0);
    if (code) {
	if (code == KTC_NOCM || code == KTC_NOCMRPC)
	    *reasonP = "AFS service may not have started";
	else if (code == KTC_RPC)
	    *reasonP = "RPC failure in AFS gateway";
	else if (code == KTC_NOCELL)
	    *reasonP = "unknown cell";
	else
	    *reasonP = "unknown error";
    }

    return code;
}
Пример #9
0
/* if it's from DNS, see if it has expired 
 * and check to make sure we have a valid set of volume servers
 * this function must be called with a Write Lock on cm_cellLock
 */
cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags)
{
    long code = 0;
    cm_cell_rock_t rock;

    if (cp == NULL)
        return NULL;

    lock_ObtainMutex(&cp->mx);
    if ((cp->vlServersp == NULL 
#ifdef AFS_FREELANCE_CLIENT
          && !(cp->flags & CM_CELLFLAG_FREELANCE)
#endif
          ) || (time(0) > cp->timeout)
#ifdef AFS_AFSDB_ENV
        || (cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) &&
         ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID)))
#endif
            ) 
    {
        lock_ReleaseMutex(&cp->mx);

        /* must empty cp->vlServersp */
        if (cp->vlServersp) {
            cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE);
            cp->vlServersp = NULL;
        }

        rock.cellp = cp;
        rock.flags = flags;
        code = cm_SearchCellFileEx(cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
        if (code == 0) {
            lock_ObtainMutex(&cp->mx);
	    cp->timeout = time(0) + 7200;
            lock_ReleaseMutex(&cp->mx);
        }
#ifdef AFS_AFSDB_ENV
        else {
            if (cm_dnsEnabled) {
                int ttl;

                code = cm_SearchCellByDNS(cp->name, NULL, &ttl, cm_AddCellProc, &rock);
                if (code == 0) {   /* got cell from DNS */
                    lock_ObtainMutex(&cp->mx);
                    cp->flags |= CM_CELLFLAG_DNS;
                    cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
		    cp->timeout = time(0) + ttl;
                    lock_ReleaseMutex(&cp->mx);
#ifdef DEBUG
                    fprintf(stderr, "cell %s: ttl=%d\n", cp->name, ttl);
#endif
		} else {
                    /* if we fail to find it this time, we'll just do nothing and leave the
                     * current entry alone 
		     */
                    lock_ObtainMutex(&cp->mx);
                    cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
                    lock_ReleaseMutex(&cp->mx);
                }
	    }
	}
#endif /* AFS_AFSDB_ENV */
    } else {
        lock_ReleaseMutex(&cp->mx);
    }
    return code ? NULL : cp;
}