I’m trying to implement a solar system with a camera that can fly through it with six degrees of freedom. However, I’m still having trouble getting my head around the duality of the model and view transformations. I get the model placed OK with sun, planets, and moons, pushes and pops, etc., but when the camera/view comes into play my head explodes.

Can someone give me advice as to how to proceed with a camera/view? Is it preferable to use gluLookAt() and modify up, lookAt, and position vectors or “roll your own” and keep track of pitch, heading, and roll? Or maybe a combination of both?

For each object, including the camera, keep a position and an orientation (typically, a Triple and a Quaternion).

Think of it like this:
First, the model rotates around its own origin.
Then, the model is translated to its position relative the camera.
Last, the model is rotated using the inverse of the camera rotation, around the camera.

The modelview to use to draw an object O when the camera is C, is then constructed as such:

Instead of using a sequence of translate/rotate, you can turn this sequence of operations into a quat/triple pair and turn that into a single matrix using your favourite Quaternion class (most of 'em have this built in) and LoadMatrix into your modelview. (You may need to transpose the matrix, depending on the specifics of your quaternion class)

No need to push/pop; just re-generate this matrix for each object – because each object has a different model matrix anyway, there is no extra cost in doing so; in fact, it’s the simplest way possible to do it.