Programmers faced with this sort of problem for the first time often end up implementing an approach that looks more or less like this:
snprintf(filename, "/tmp/mbox.%s", getlogin());
...
if (lstat(filename, &stb) >= 0 || S_ISLNK(stb.st_mode))
fatal("*** symlink attack ***");
fp = fopen(filename, "w");
While this stops the simple form of the attack, it doesn't really protect you.
The first problem is that it doesn't help against hard links. An attacker can create a hard link named mbox.joe to any file on the same file system as /tmp. On many systems, where /tmp resides in the root file system, this includes files in /etc, so the root user would be a promising target.
The second problem is that the lstat call and subsequent file operation are not atomic, i.e. a certain amount of time passes between the lstat check and the fopen call during which a context switch may occur, and another process started by the attacker would be allowed to run. During that time window, the attacker could create the symlink.
This is called a race condition.
This sounds like a very hypothetical sort of attack, because the time window is just a couple of milliseconds. To illustrate why this is a very real threat, I'll describe some common attacks against this type of code.