ruid = getuid(); rgid = getgid(); #ifdef HAS_SAVED_IDS_AND_SETEUID euid = geteuid(); egid = getegid();  if (euid != ruid || egid != rgid) {  if (seteuid(ruid) == -1 || setegid(rgid) == -1) { return BadAccess; } } #endif
ProcShmAttach(client)    register ClientPtr client;{    struct shmid_ds buf;    ShmDescPtr shmdesc;    REQUEST(xShmAttachReq);    uid_t ruid;    gid_t rgid;#ifdef HAS_SAVED_IDS_AND_SETEUID    uid_t euid;    gid_t egid;#endif    REQUEST_SIZE_MATCH(xShmAttachReq);    LEGAL_NEW_RESOURCE(stuff->shmseg, client);    if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))    {	client->errorValue = stuff->readOnly;        return(BadValue);    }    for (shmdesc = Shmsegs;	 shmdesc && (shmdesc->shmid != stuff->shmid);	 shmdesc = shmdesc->next)	;    if (shmdesc)    {	if (!stuff->readOnly && !shmdesc->writable)	    return BadAccess;	shmdesc->refcnt++;    }    else    {	shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));	if (!shmdesc)	    return BadAlloc;	ruid = getuid();	rgid = getgid();#ifdef HAS_SAVED_IDS_AND_SETEUID	euid = geteuid();	egid = getegid();	if (euid != ruid || egid != rgid) {	    /* Temporarly switch back to real ids */	    if (seteuid(ruid) == -1 || setegid(rgid) == -1) {		return BadAccess;	    }	}#endif	shmdesc->addr = shmat(stuff->shmid, 0,			      stuff->readOnly ? SHM_RDONLY : 0);#ifdef HAS_SAVED_IDS_AND_SETEUID	if (euid != ruid || egid != rgid) {	    /* Switch back to root privs */	    if (seteuid(euid) == -1 || setegid(egid) == -1) {		return BadAccess;	    }	} #endif	if ((shmdesc->addr == ((char *)-1)) ||	    shmctl(stuff->shmid, IPC_STAT, &buf))	{	    xfree(shmdesc);	    return BadAccess;	}#ifndef HAS_SAVED_IDS_AND_SETEUID	/* The attach was performed with root privs. We must	 * do manual checking of access rights for the real uid/gid */	if (shm_access(ruid, rgid, &(buf.shm_perm), stuff->readOnly) == -1) {	    shmdt(shmdesc->addr);	    xfree(shmdesc);	    return BadAccess;	}#endif		shmdesc->shmid = stuff->shmid;	shmdesc->refcnt = 1;	shmdesc->writable = !stuff->readOnly;	shmdesc->size = buf.shm_segsz;	shmdesc->next = Shmsegs;	Shmsegs = shmdesc;    }    if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))	return BadAlloc;    return(client->noClientException);}