I haven't looked closely at your code, but are you aware that it is usually necessary to change GID before UID? Once you've changed UID, you no longer have appropriate permissions to change GID.
I should imagine that similar restrictions apply to effective vs real, but I can't remember off the top of my head.