static char rcsid[] = "@(#)$Id: can_access.c,v 1.11 2006/04/09 07:37:05 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.11 $ $State: Exp $
*
* Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* (was hurtta+elm@ozone.FMI.FI)
******************************************************************************
* The Elm Mail System
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
/** can_access - can this user access this file using their normal uid/gid
**/
/* WHAT HELL THIS IS!
*
* access -system call uses real uid / gid anyway !!!!!
*
* - K E H <hurtta@ozone.FMI.FI>
*/
#include "headers.h"
#include <errno.h>
#ifndef ANSI_C
extern int errno; /* system error number */
#endif
#ifndef I_UNISTD
void _exit();
#endif
int can_access(file, mode)
char *file;
int mode;
{
/** returns ZERO iff user can access file or "errno" otherwise **/
int the_stat = 0, pid, w;
struct stat stat_buf;
#if defined(BSD_TYPE) && !defined(WEXITSTATUS)
union wait status;
#else
int status;
#endif
#ifdef VFORK
if ((pid = vfork()) == 0) {
#else
if ((pid = fork()) == 0) {
#endif
/* Why we are returning to real gid/uid --
access() uses them anyway!
*/
if (-1 == setgid(groupid)) {
int err = errno;
fprintf(stderr,"can_access: setgid(%d) FAILED: %s\n",
groupid,error_description(err));
fflush(stderr);
_exit(err != 0? err : 1); /* never return zero! */
}
if (-1 == setuid(userid)) { /** back to normal userid **/
int err = errno;
fprintf(stderr,"can_access: setuid(%d) FAILED: %s\n",
userid,error_description(err));
fflush(stderr);
_exit(err != 0? err : 1); /* never return zero! */
}
errno = 0;
if (access(file, mode) == 0)
_exit(0);
else
_exit(errno != 0? errno : 1); /* never return zero! */
_exit(127);
}
errno = 0;
while (((w = my_wait(pid,&status)) != pid && w != -1) ||
EINTR == errno)
;
if (w == -1) {
the_stat = errno;
if (!the_stat)
the_stat = 1;
} else {
int sig = convert_status(status,&the_stat);
if (sig)
the_stat = 1;
}
if (the_stat == 0) {
if (stat(file, &stat_buf) == 0) {
#ifndef _POSIX_SOURCE
w = stat_buf.st_mode & S_IFMT;
if (w != S_IFREG)
the_stat = 1;
#else /* _POSIX_SOURCE */
w = stat_buf.st_mode;
if (! S_ISREG(w))
the_stat = 1;
#endif
}
}
return(the_stat);
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1