LQ Newbie
Registered: May 2013
Location: Southeast
Distribution: RHE6.3
Posts: 5
Rep:
|
Need help with c program porting from Solaris10 to RHL6.3
We have a C program called su-someone that was created in 1990. Our C programmer moved out into the world years ago. Now we are converting from Solaris10 to RHL6.3. I copied the C program over and compiled it and have errors. I need help solving the errors please. Here is the code:
/* NAME
su-someone 1
SUMMARY
use your own password to switch to another user ID
SYNOPSIS
su-\fIsomeone\fR [arguments]
DESCRIPTION
The su-\fIsomeone\fR command allows a limited group of users to
work under a given user id (e.g. \fIsomeone\fR) without having know
its password. Users have to enter \fItheir own\fR password in
order to get the privileges of the \fIsomeone\fR account.
After successful validation the user is given a shell process
(default: /bin/sh) with the appropriate uid, gid and with a sane
environment and umask. Where possible, the shell prompt will reflect
the uid of that process.
Any arguments given to su-\fIsomeone\fR are passed as arguments to the
shell process.
Only authorized users are allowed to use this command; in
order to make cheating a bit more difficult, the table of authorized
users is compiled into the program.
With BSD-like UNIX implementations, the executable file should be
installed set-uid and set-gid to the \fIsomeone\fR account.
With System-V Release 2, the executable should be set-uid root and
the \fIsomeone\fR account name must be wired into the program.
You can give the executable any name you want, but be sure that
only the owner can overwrite it.
COMMANDS
/bin/sh, other login shells.
FILES
/dev/tty, to read the password.
Shell startup files, but usually no login procedures.
ENVIRONMENT VARIABLES
SHELL, PATH, IFS, HOME and PS1 are overwritten.
SEE ALSO
su(1)
DIAGNOSTICS
The program prints a diagnostic and terminates with a non-zero
exit status if there are problems (authorization, environment
update, shell startup).
AUTHOR(S)
Wietse Venema
Eindhoven University of Technology
Department of Mathematics and Computer Science
Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
LAST MODIFICATION
90/05/27 20:54:03
VERSION/RELEASE
1.7
--*/
/*
* This program is in the public domain. You can do anything with it as long
* as you do not remove the references to the original author.
*/
#ifndef lint
static char sccsid[] = "@(#) su-someone.c 1.7 90/05/27 20:54:03";
#endif
#include <stdio.h>
#include <pwd.h>
#include <varargs.h>
#include <sys/types.h>
#include <time.h>
#include <signal.h>
#include <shadow.h>
/*
* The first purpose of the program is to avoid the security problems that
* arise when a password has to be known to several people.
*
* The second purpose of the program is to set up a decent environment: shell,
* umask, path, home and field separators.
*
* The default is to invoke the Bourne shell. If you want to use the shell as
* specified in the password data base, define USE_HER_SHELL.
*/
#ifdef USE_HER_SHELL
#define SHELL (*pwd->pw_shell ? pwd->pw_shell : "/bin/sh")
#else
#define SHELL "/bin/sh"
#endif
/*
* Logging values
*/
#define USER_OK '+'
#define USER_BAD '-'
#define USER_OUT '!'
char logfilename[] = "/usr/adm/sulog";
FILE *logfile;
struct {
char *progname;
char ttyname[20];
char logname[12];
} sulogrec;
#define UMASK 022
#define PATH "/usr/ucb:/bin:/usr/bin:/usr/local/bin:."
#define IFS " \t\n"
/* Library functions... */
extern struct passwd *getpwuid();
extern struct passwd *getpwnam();
extern char *getpass();
extern char *crypt();
extern void exit();
extern void perror();
extern char *rindex();
extern char *malloc();
/* Local stuff... */
static char *progname;
static int islegal();
static void giveup();
static void logattempt();
struct spwd *getshadow();
/*
inttrap ()
{
putchar(7);
signal (SIGINT,SIG_IGN);
}
quittrap ()
{
putchar(7);
signal (SIGQUIT,SIG_IGN);
}
*/
int main(argc, argv)
int argc;
char **argv;
{
struct passwd *pwd;
struct spwd *spwd;
char ps1[BUFSIZ];
char *pass;
int frkreturn;
static int fildes = 0;
progname = *argv;
/*
signal (SIGINT,SIG_IGN);
signal (SIGQUIT,SIG_IGN);
*/
if ( isatty(fildes) )
{
strcpy(sulogrec.ttyname,ttyname(fildes));
}
else
giveup("Not a TTY");
sulogrec.progname = *argv;
logfile = fopen(logfilename,"a");
if ( logfile == (FILE *)NULL )
giveup("Unable to open logfile");
/* Validate the user who invoked us. */
if ((pwd = getpwuid(getuid())) == NULL)
giveup("I don't know you");
strcpy(sulogrec.logname,pwd->pw_name);
if (!islegal(pwd->pw_name))
giveup("You are not authorized to use this program");
if ((pass = getpassphrase("Enter YOUR OWN password:")) == 0)
giveup("Can't read your password");
/* test for shadow password */
if (strcmp(pwd->pw_passwd,"x") == 0 || pwd->pw_passwd[0] == '\0')
{
if ((spwd = getspnam(pwd->pw_name)) == (struct spwd*)NULL)
giveup("Can't locate shadow record");
pwd->pw_passwd = spwd->sp_pwdp;
}
if (strcmp(pwd->pw_passwd, crypt(pass, pwd->pw_passwd)) != 0)
giveup("Sorry");
/*
* Erase the password now that we do not need it anymore. This avoids a
* security problem should we ever dump core.
*/
while (*pass)
*pass++ = 0;
/*
* With SYSV-like UNIX, install the program set-uid root. The program will
* deduce the desired uid, gid from a hard-wired name.
*/
if ((pwd = getpwnam("root")) == 0)
giveup("I don't know '%s'", "root");
/* Switch to the desired uid, gid. */
/* Do not set gid as of 9/15/00
if (setgid(pwd->pw_gid))
giveup("setgid(%d) failed", pwd->pw_gid);
*/
if (setuid(pwd->pw_uid))
giveup("setuid(%d) failed", pwd->pw_uid);
/*
* Change the prompt to alert the user to new permissions
*
*/
(void) putenv("PS1=SUPER-USER # ");
/*
* Ready to invoke a shell. All arguments given to us are passed on to
* that shell.
*/
if ((argv[0] = rindex(SHELL, '/')) == 0)
argv[0] = SHELL;
else
argv[0]++; /* skip '/' character */
/* Log attempt */
logattempt(USER_OK);
/* run in subshell */
frkreturn = gofork(argv,SHELL);
/* test return */
printf("\nSUPER-USER status terminated (%d)\n\7",frkreturn);
/* Log attempt */
logattempt(USER_OUT);
fclose (logfile);
exit(frkreturn);
}
int
gofork (argv,shell)
char **argv;
char *shell;
{
int cpid, status;
cpid = fork ();
switch (cpid)
{
case -1: /* Cannot fork. */
return -1; /* errno is set already. */
case 0: /* Child process. */
(void) execv(shell, argv);
giveup("Can't invoke %s", shell);
default: /* Parent process. */
while (wait (&status) != cpid) /* Wait for kid to finish. */
/* Do nothing. */ ;
return 0;
}
}
/* islegal - check user is in table of legal names */
static int islegal(logname)
char *logname;
{
char *cryptname();
char **cpp;
static char *legalname[] = {
"sDkAEGlUhh",
"Yw1F12WnxV",
"u99Iyr1BOQ",
"JlIkOGhvAs",
"5tvSozBsOG",
"586HkYHvhq",
"QRUNv5wjd8",
"17m.P3F9pP",
"BLToPR9vrB",
"WeZ.eaOdbW",
"Ic7BCGyKY.",
"Xxno9eLnyA",
"YwrkSBO1d5",
0, /* TERMINATOR */
};
for (cpp = legalname; *cpp; cpp++) {
if (0 == strcmp(cryptname(logname), *cpp))
return (1);
}
return (0);
}
/* giveup - print diagnostic on the standard error output and terminate */
/* VARARGS */
static void giveup(va_alist)
va_dcl
{
va_list ap;
char *fmt;
/* Log attempt */
logattempt(USER_BAD);
(void) fprintf(stderr, "%s: ", progname);
va_start(ap);
fmt = va_arg(ap, char *);
(void) vfprintf(stderr, fmt, ap);
va_end(ap);
(void) putc('\n', stderr);
exit(1);
}
#define maxpasslen 10
char *cryptname(logname)
char *logname;
{
char * crypt();
static char salt[2] = { '.','/'};
char *cname;
cname = crypt(logname,salt);
cname += 2;
*(cname + maxpasslen) = '\0';
return (cname);
}
void logattempt (status)
char status;
{
time_t ltm;
struct tm *time_st;
ltm = time((long *)0);
time_st = localtime(<m);
fprintf(logfile,"%s %02d/%02d %02d:%02d %c %s %s-%s\n",
sulogrec.progname,
(time_st->tm_mon)+1,
time_st->tm_mday,
time_st->tm_hour,
time_st->tm_min,
status,
sulogrec.ttyname,
sulogrec.logname,
"root");
fflush(logfile);
}
/*
struct spwd *getshadow(const char *name)
{
struct spwd *spwd;
FILE *shadow;
if (shadow = fopen("/etc/shadow","r") != (FILE*)NULL)
{
while (fgets(buf,shadow) != (char*)NULL)
{
}
while ((spwd = getspent()) != (struct spwd*)NULL)
{
printf("name = %s pw = %s\n",spwd->sp_namp, spwd->sp_pwdp);
if (strcmp(spwd->sp_namp,name) == 0)
return(spwd->sp_pwdp);
}
return (NULL);
}
*/
|