Beispiel #1
0
/*
 * Determine if requester is allowed to update the given map,
 * and update it if so. Returns the yp status, which is zero
 * if there is no access violation.
 */
int
mapupdate(char *requester, char *mapname, u_int op, u_int keylen, char *key,
    u_int datalen, char *data)
{
	char updater[MAXMAPNAMELEN + 40];
	FILE *childargs;
	FILE *childrslt;
#ifdef WEXITSTATUS
	int status;
#else
	union wait status;
#endif
	pid_t pid;
	u_int yperrno;


#ifdef DEBUG
	printf("%s %s\n", key, data);
#endif
	(void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */
					UPDATEFILE, mapname);
	pid = _openchild(updater, &childargs, &childrslt);
	if (pid < 0) {
		return (YPERR_YPERR);
	}

	/*
	 * Write to child
	 */
	(void)fprintf(childargs, "%s\n", requester);
	(void)fprintf(childargs, "%u\n", op);
	(void)fprintf(childargs, "%u\n", keylen);
	(void)fwrite(key, (int)keylen, 1, childargs);
	(void)fprintf(childargs, "\n");
	(void)fprintf(childargs, "%u\n", datalen);
	(void)fwrite(data, (int)datalen, 1, childargs);
	(void)fprintf(childargs, "\n");
	(void)fclose(childargs);

	/*
	 * Read from child
	 */
	(void)fscanf(childrslt, "%d", &yperrno);
	(void)fclose(childrslt);

	(void)wait(&status);
#ifdef WEXITSTATUS
	if (WEXITSTATUS(status) != 0)
#else
	if (status.w_retcode != 0)
#endif
		return (YPERR_YPERR);
	return (yperrno);
}
Beispiel #2
0
/*
 * Determine if requester is allowed to update the given map,
 * and update it if so. Returns the yp status, which is zero
 * if there is no access violation.
 */
int
mapupdate(char *requester, char *mapname, u_int op, u_int keylen,
    char *key, u_int datalen, char *data)
{
	char updater[MAXMAPNAMELEN + 40];
	FILE *childargs;
	FILE *childrslt;
#ifdef WEXITSTATUS
	int status;
#else
	union wait status;
#endif
	pid_t pid;
	u_int yperrno;


#ifdef DEBUG
	printf("%s %s\n", key, data);
#endif
	(void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */
					UPDATEFILE, mapname);
	pid = _openchild(updater, &childargs, &childrslt);
	if (pid < 0) {
		return (YPERR_YPERR);
	}

	/*
	 * Write to child
	 */
	(void)fprintf(childargs, "%s\n", requester);
	(void)fprintf(childargs, "%u\n", op);
	(void)fprintf(childargs, "%u\n", keylen);
	(void)fwrite(key, (int)keylen, 1, childargs);
	(void)fprintf(childargs, "\n");
	(void)fprintf(childargs, "%u\n", datalen);
	(void)fwrite(data, (int)datalen, 1, childargs);
	(void)fprintf(childargs, "\n");
	(void)fclose(childargs);

	/*
	 * Read from child
	 */
	(void)fscanf(childrslt, "%d", &yperrno);
	(void)fclose(childrslt);

	(void)wait(&status);
#ifdef WEXITSTATUS
	if (WEXITSTATUS(status) != 0) {
#else
	if (status.w_retcode != 0) {
#endif
		return (YPERR_YPERR);
	}
	return (yperrno);
}

/*
 * returns pid, or -1 for failure
 */
static pid_t
_openchild(char *command, FILE **fto, FILE **ffrom)
{
	int i;
	pid_t pid;
	int pdto[2];
	int pdfrom[2];
	char *com;
	struct rlimit rl;

	if (pipe(pdto) < 0) {
		goto error1;
	}
	if (pipe(pdfrom) < 0) {
		goto error2;
	}
	switch (pid = fork()) {
	case -1:
		goto error3;

	case 0:
		/*
		 * child: read from pdto[0], write into pdfrom[1]
		 */
		(void)close(0);
		(void)dup(pdto[0]);
		(void)close(1);
		(void)dup(pdfrom[1]);
		getrlimit(RLIMIT_NOFILE, &rl);
		for (i = rl.rlim_max - 1; i >= 3; i--) {
			(void) close(i);
		}
		com = malloc((unsigned) strlen(command) + 6);
		if (com == NULL) {
			_exit(~0);
		}
		(void)sprintf(com, "exec %s", command);
		execl(SHELL, basename(SHELL), "-c", com, (char *)NULL);
		_exit(~0);

	default:
		/*
		 * parent: write into pdto[1], read from pdfrom[0]
		 */
		*fto = fdopen(pdto[1], "w");
		(void)close(pdto[0]);
		*ffrom = fdopen(pdfrom[0], "r");
		(void)close(pdfrom[1]);
		break;
	}
	return (pid);

	/*
	 * error cleanup and return
	 */
error3:
	(void)close(pdfrom[0]);
	(void)close(pdfrom[1]);
error2:
	(void)close(pdto[0]);
	(void)close(pdto[1]);
error1:
	return (-1);
}
Beispiel #3
0
static int
internal_function
key_call_keyenvoy (u_long proc, xdrproc_t xdr_arg, char *arg,
		   xdrproc_t xdr_rslt, char *rslt)
{
  XDR xdrargs;
  XDR xdrrslt;
  FILE *fargs;
  FILE *frslt;
  sigset_t oldmask, mask;
  union wait status;
  int pid;
  int success;
  uid_t ruid;
  uid_t euid;
  static const char MESSENGER[] = "/usr/etc/keyenvoy";

  success = 1;
  sigemptyset (&mask);
  sigaddset (&mask, SIGCHLD);
  __sigprocmask (SIG_BLOCK, &mask, &oldmask);

  /*
   * We are going to exec a set-uid program which makes our effective uid
   * zero, and authenticates us with our real uid. We need to make the
   * effective uid be the real uid for the setuid program, and
   * the real uid be the effective uid so that we can change things back.
   */
  euid = __geteuid ();
  ruid = __getuid ();
  __setreuid (euid, ruid);
  pid = _openchild (MESSENGER, &fargs, &frslt);
  __setreuid (ruid, euid);
  if (pid < 0)
    {
      debug ("open_streams");
      __sigprocmask (SIG_SETMASK, &oldmask, NULL);
      return (0);
    }
  xdrstdio_create (&xdrargs, fargs, XDR_ENCODE);
  xdrstdio_create (&xdrrslt, frslt, XDR_DECODE);

  if (!INTUSE(xdr_u_long) (&xdrargs, &proc) || !(*xdr_arg) (&xdrargs, arg))
    {
      debug ("xdr args");
      success = 0;
    }
  fclose (fargs);

  if (success && !(*xdr_rslt) (&xdrrslt, rslt))
    {
      debug ("xdr rslt");
      success = 0;
    }
  fclose(frslt);

 wait_again:
  if (__wait4 (pid, &status, 0, NULL) < 0)
    {
      if (errno == EINTR)
	goto wait_again;
      debug ("wait4");
      if (errno == ECHILD || errno == ESRCH)
	perror ("wait");
      else
	success = 0;
    }
  else
    if (status.w_retcode)
      {
	debug ("wait4 1");
	success = 0;
      }
  __sigprocmask (SIG_SETMASK, &oldmask, NULL);

  return success;
}
Beispiel #4
0
/*
 * Determine if requester is allowed to update the given map,
 * and update it if so. Returns the yp status, which is zero
 * if there is no access violation.
 */
int
mapupdate(char *name, char *mapname, uint_t op, char *data)
{
	char	updater[MAXMAPNAMELEN + 40];
	FILE	*childargs;
	FILE	*childrslt;
#ifdef WEXITSTATUS
	int	status;
#else
	union wait status;
#endif
	pid_t	pid;
	uint_t	yperrno;
	int	namelen, datalen;
	struct	stat	stbuf;

#ifdef DEBUG
	(void) fprintf(stderr, "%s %s\n", name, data);
#endif
	namelen = strlen(name);
	datalen = strlen(data);
	errno = 0;
	if (stat(MAKE, &stbuf) < 0)
		switch (errno) {
		case ENOENT:
			(void) fprintf(stderr,
			"%s: %s not found, please install on the system\n",
			program_name, MAKE);
			return (1);
		default:
			(void) fprintf(stderr,
				"%s: cannot access %s, errno=%d.\n",
				program_name, MAKE, errno);
			return (1);
		}
	(void) sprintf(updater, "%s -s -f %s %s",
			MAKE, UPDATEFILE, mapname);
	pid = _openchild(updater, &childargs, &childrslt);
	if (pid < 0)
		return (YPERR_YPERR);

	/*
	 * Write to child
	 */
	(void) fprintf(childargs, "%s\n", name);
	(void) fprintf(childargs, "%u\n", op);
	(void) fprintf(childargs, "%u\n", namelen);
	(void) fwrite(name, namelen, 1, childargs);
	(void) fprintf(childargs, "\n");
	(void) fprintf(childargs, "%u\n", datalen);
	(void) fwrite(data, datalen, 1, childargs);
	(void) fprintf(childargs, "\n");
	(void) fclose(childargs);

	/*
	 * Read from child
	 */
	(void) fscanf(childrslt, "%d", &yperrno);
	(void) fclose(childrslt);

	(void) wait(&status);
#ifdef WEXITSTATUS
	if (WEXITSTATUS(status) != 0) {
#else
	if (status.w_retcode != 0) {
#endif
		return (YPERR_YPERR);
	}
	return (yperrno);
}

/*
 * returns pid, or -1 for failure
 */
static int
_openchild(char *command, FILE **fto, FILE **ffrom)
{
	int i;
	pid_t pid;
	int pdto[2];
	int pdfrom[2];
	char *com;

	if (pipe(pdto) < 0) {
		goto error1;
	}
	if (pipe(pdfrom) < 0) {
		goto error2;
	}
#ifdef VFORK
	switch (pid = vfork()) {
#else
	switch (pid = fork()) {
#endif
	case -1:
		goto error3;

	case 0:
		/*
		 * child: read from pdto[0], write into pdfrom[1]
		 */
		(void) close(0);
		(void) dup(pdto[0]);
		(void) close(1);
		(void) dup(pdfrom[1]);
		closefrom(3);
		com = malloc((unsigned)strlen(command) + 6);
		if (com == NULL) {
			_exit(~0);
		}
		(void) sprintf(com, "exec %s", command);
		execl(SHELL, basename(SHELL), "-c", com, NULL);
		_exit(~0);

	default:
		/*
		 * parent: write into pdto[1], read from pdfrom[0]
		 */
		*fto = fdopen(pdto[1], "w");
		(void) close(pdto[0]);
		*ffrom = fdopen(pdfrom[0], "r");
		(void) close(pdfrom[1]);
		break;
	}
	return (pid);

	/*
	 * error cleanup and return
	 */
error3:
	(void) close(pdfrom[0]);
	(void) close(pdfrom[1]);
error2:
	(void) close(pdto[0]);
	(void) close(pdto[1]);
error1:
	return (-1);
}

static char *
basename(char *path)
{
	char	*p;

	p = strrchr(path, '/');
	if (p == NULL)
		return (path);
	return (p + 1);
}