Classic bug: Reused deleted team identifiers
| Bug ID | GE-BUG-015 |
|---|---|
| Affected versions | Classic 3.2e and published classic source |
| Status | Verified in source; corrected in ge-next 0.3 |
| Fixed in | ge-next 0.3 |
| Primary source | Classic GEMAIN.C: midnight(), update_team_tab(); GECMDS.C: TEAM START, team-protected trading; ge-next GEMAIN.C: fixplanetteam(); GECMDS.C: TEAM START |
Summary
Classic Galactic Empire identifies a team by a player-chosen five-digit numeric code. A planet configured with the special team trade password stores that number in its own teamcode field. If the team later disappears, the planet can retain the number. Classic can then allow a newly created, unrelated team to choose the same code and gain access to that planet as though it were the former team.
How the code becomes available again
During midnight cleanup, classic rebuilds team member counts from saved user records. A team with no counted members is marked for removal by setting its table entry's code to -1. update_team_tab() omits that entry when rewriting the flat team file. The deletion does not scan every planet for the team's numeric code or clear team passwords on those planets.
TEAM START checks a proposed code against the team entries that still exist. Once the old entry has been removed, its code is no longer reserved. A later founder can use those same five digits for a different team. Reusing a slot in the in-memory team table is not itself the problem; reusing the numeric identity is.
Classic's team-protected trading path compares the player's WARUSR.teamcode directly with the planet's stored teamcode. The planet has no generation number or other way to tell that the new team is unrelated to the one for which the password was set.
Example
- Alice owns a planet and, while on Team Red with code
12345, sets its trade password toteam. The planet stores12345. - Red loses its last saved member. At cleanup, classic removes Red's team entry, but the planet still stores
12345. - Bob creates Team Blue using code
12345.TEAM STARTaccepts it because Red's old entry is gone. - Blue's members now satisfy the planet's numeric team check. The planet has effectively acquired an unintended relationship with Blue even though its owner never authorized Blue.
This concerns team-password access to a planet, not a transfer of planet ownership. The same code can be reused even when all team member counts were correct; the loss of identity history is the underlying defect.
Relationship to other team bugs
GE-BUG-014 describes how classic's JOIN, START, UNJOIN, and KICK paths can leave the active user record, saved membership, and cached team counts out of agreement until cleanup. Those discrepancies can change when classic believes a team has become empty, and a stale user team code can complicate later reconciliation. GE-BUG-015 is distinct: even with accurate membership accounting, deleting the only record of a numeric team identity leaves old planet references able to match a future team with that code.
The two fixes address different layers. Immediate membership and count updates make team state current; retaining deleted codes prevents ordinary reuse of a former team identity while a planet may still refer to it.
Correction in ge-next 0.3
The 0.3 team overhaul keeps a deleted team as an @DELETED@ tombstone. It records the deletion day and erases the team's passwords, but retains its numeric code. TEAM START rejects a proposed code if it matches either a live team or a retained tombstone. An old code therefore does not immediately become available when a team disbands, fixing the normal classic failure path.
ge-next also validates planets using the team trade password through fixplanetteam(). If a planet's code no longer points to a live team, the helper clears the team code and password when the planet is encountered through the relevant gameplay paths. This removes stale planet references as they are found. Both changes were introduced in ge-next 0.3 and apply to the 16-bit and 32-bit versions.
Bounded tombstone history
The team table has 50 slots. If every slot is occupied, TEAM START deliberately reuses the oldest deleted slot rather than permanently exhausting the table. That replaces its tombstone, so its former code could eventually be chosen again. This is a capacity tradeoff, not an accidental omission from the 0.3 correction.
In principle, someone could try to exploit this by creating and deleting enough teams to displace a particular tombstone, then starting a new team with that exact old code while a planet still carries it. Doing so would require knowledge of the old team's five-digit code and the game's internal tombstone behavior, enough team churn to evict that entry, and a matching planet that has not already had its obsolete team password cleared. The effort and specific conditions make this a remote scenario rather than the ordinary code-reuse bug present in classic.
Porting guidance
Team codes stored on planets are persistent relationships, not just display labels. Preserve deleted identities long enough to prevent routine code reuse, and validate stale planet references when those planets are accessed. A port that requires a strict guarantee against reuse under arbitrary team churn can use durable, non-reusable identifiers or transactionally clear every reference before making an identifier available again; ge-next instead uses bounded tombstones and on-access cleanup.
Home · Play · Reference · Versions & history · Sysop · Development · Classic bugs