/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#define BSD_COMP
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sac.h> /* for SC_WILDC */
#include <utmpx.h>
/*
*
*
*
* # include <pwdadj.h>
*/
#include <stropts.h>
#include "rex.h"
#include <security/pam_appl.h>
/*
* unix_login - hairy junk to simulate logins for Unix
*/
static char *slavename;
extern char *ptsname();
/*
* pseudo-xprts used to add pty fds to svc_pollfd[]. This allows the
* polling for all i/o in one poll().
*/
extern int child; /* pid of the executed process */
extern int ChildDied; /* flag */
extern int HasHelper; /* flag */
extern int Debug;
char *, char **);
static void LogoutUser(void);
/*
* Check for user being able to run on this machine.
* returns 0 if OK, TRUE if problem, error message in "error"
* copies name of shell and home directory if user is valid.
*/
int
char *host; /* passed in */
char *error; /* filled in on return */
char *shell; /* filled in on return */
char *dir; /* filled in on return */
{
int v;
{
audit_rexd_fail("user id is not valid",
host,
NULL,
uid,
gid,
NULL,
return (1);
}
audit_rexd_fail("user id is not valid",
host,
uid,
gid,
if (pamh) {
}
return (1);
}
switch (v) {
case PAM_NEW_AUTHTOK_REQD:
"rexd: User id %d Password Expired\n", uid);
break;
case PAM_PERM_DENIED:
"rexd: User id %d Account Expired\n", uid);
break;
case PAM_AUTHTOK_EXPIRED:
"rexd: User id %d Password Expired\n", uid);
break;
default:
"rexd: User id %d not valid\n", uid);
break;
}
audit_rexd_fail("user account expired",
host,
uid,
gid,
return (1);
}
return (0);
}
/*
* Add an audit record with argv that was pre-set, plus the given string
*/
/*
* Allocate a pseudo-terminal
* sets the global variables Master and Slave.
* returns 1 on error, 0 if OK
*/
int
{
if (Debug)
printf("open-ptmx-failure\n");
perror("AloocatePtyMaster fails");
}
if (Debug)
if (Debug)
perror("could not grant slave pty");
exit(1);
}
perror("could not unlock slave pty");
exit(1);
}
perror("could not enable slave pty");
exit(1);
}
perror("could not open slave pty");
exit(1);
}
perror("ioctl I_PUSH ptem");
exit(1);
}
perror("ioctl I_PUSH ldterm");
exit(1);
}
perror("ioctl I_PUSH ttcompat");
exit(1);
}
setsid(); /* get rid of controlling terminal */
/* LoginUser(); */
return (0);
}
void
{
if (Slave < 0) {
exit(1);
}
}
/*
* Special processing for interactive operation.
* Given pointers to three standard file descriptors,
* which get set to point to the pty.
*/
void
{
int pgrp;
}
/*
* destroy the helpers when the executing process dies
*/
void
{
if (Debug)
printf("Enter KillHelper\n");
LogoutUser();
if (grp)
}
/*
* edit the Unix traditional data files that tell who is logged
* into "the system"
*/
void
LoginUser(void)
{
char *user;
char *rhost;
/* the next 4 variables are needed for utmpx mgmt */
int tmplen;
char *ttyntail;
/* We're pretty drastic here, exiting if an error is detected */
/*
* XXX should print something but for now we exit
*/
exit(1);
}
else
} else {
}
/*
* Copy in the name of the tty minus the "/dev/" if a /dev/ is
* in the path name.
*/
/*
* Go through each entry one by one, looking only at INIT,
* LOGIN or USER Processes. Use the entry found if flags == 0
* and the line name matches, or if the process ID matches if
* the UPDATE_ENTRY flag is set. The UPDATE_ENTRY flag is mainly
* for login which normally only wants to update an entry if
* the pid fields matches.
*/
} else
}
/*
* edit the Unix traditional data files that tell who is logged
* into "the system".
*/
static void
LogoutUser(void)
{
int pid;
if (pamh) {
}
/* BEGIN RESET UTMP */
setutxent();
/*
* Cleaned up elsewhere.
*/
break;
}
== PAM_SUCCESS) {
(void) pam_close_session(pamh, 0);
}
/*
* Since modutx failed we'll
* write out the new entry
* ourselves.
*/
(void) pututxline(up);
}
break;
}
}
endutxent();
/* END RESET UTMP */
}
/*
* set the pty modes to the given values
*/
void
struct rex_ttymode *mode;
{
if (Debug)
printf("Enter SetPtyMode\n");
if (Debug)
printf("SetPtyMode:opened slave\n");
if (Debug)
printf("SetPtyMode:Slave TIOCSETD done\n");
/*
* Copy from over-the-net(bsd) to SVR4 format
*/
/*
* Clear any possible sign extension caused by (int)
* typecast
*/
if (Debug)
printf("SetPtyMode:Slave TIOCSETN done\n");
if (Debug)
printf("SetPtyMode:Slave TIOCSETC done\n");
if (Debug)
printf("SetPtyMode:Slave TIOCSLTC done\n");
if (Debug)
printf("SetPtyMode:Slave TIOCSET done\n");
/* Opened in AllocPty for parent, still open in child */
if (Slave_is_closed_on_master_side == FALSE) {
}
}
/*
* set the pty window size to the given value
*/
void
{
/* if size has changed, this ioctl changes it */
/* *and* sends SIGWINCH to process group */
if (Slave_is_closed_on_master_side == FALSE) {
}
}
/*
* send the given signal to the group controlling the terminal
*/
void
{
}
/*
* called when the main select loop detects that we might want to
* read something.
*/
void
{
int retval;
extern int errno;
int mask;
/*
* fdp pollset may be compressed. Search for Master and
* InputSocket fds.
*/
int i;
for (i = 0; i < nfds; i++) {
master = i;
inputsocket = i;
}
/* mask = sigsetmask (sigmask (SIGCHLD)); */
retval = 0;
if (master != -1) {
if (retval > 0) {
} else {
errno != EWOULDBLOCK)
perror("pty read");
/* 1 => further sends disallowed */
}
}
/* clear this event for svc_getreq_poll */
HasHelper = 0;
if (inputsocket != -1) {
}
goto done;
}
}
if (inputsocket != -1) {
POLLNVAL))) {
if (retval > 0) {
} else {
perror("socket read");
}
}
/* clear this event for svc_getreq_poll */
}
done:
/* sigsetmask (mask); */
}