LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-18-2013, 03:03 PM   #1
jfaye
LQ Newbie
 
Registered: May 2013
Location: Southeast
Distribution: RHE6.3
Posts: 5

Rep: Reputation: Disabled
Question 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(&ltm);

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);
}

*/
 
Old 07-19-2013, 07:50 AM   #2
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
Why are you not using sudo which you probably already have installed?
 
Old 07-19-2013, 09:16 AM   #3
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
Is your problem that you lack the getpassphrase() function?
varargs is obsoleted by stdargs.
 
2 members found this post helpful.
Old 07-19-2013, 12:53 PM   #4
jfaye
LQ Newbie
 
Registered: May 2013
Location: Southeast
Distribution: RHE6.3
Posts: 5

Original Poster
Rep: Reputation: Disabled
Thanks for the response. I am a programmer but have never programmed in C. I will certainly check out sudo, but I would also like to get the C program to work if possible. Should I ad the getpassphrase() function to the progam.
 
Old 07-19-2013, 02:50 PM   #5
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 26,619

Rep: Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963Reputation: 7963
Quote:
Originally Posted by jfaye View Post
Thanks for the response. I am a programmer but have never programmed in C. I will certainly check out sudo, but I would also like to get the C program to work if possible. Should I ad the getpassphrase() function to the progam.
I understand your desire to get it working, but honestly, sudo does EXACTLY what you're after, and has a LOT more features. It is also an 'industry-standard' at this point, used on pretty much every flavor of *nix you can name. linosaurusroot summed things up nicely.

I'd use sudo and use the 'standard', and make the porting of this old code something you do on a rainy afternoon when you're not busy.
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Porting a C program to calculate CPU time into Linux: Segmentation fault ramesh333 Programming 5 09-29-2012 03:03 PM
DOS to Linux Program Porting (_BX Register) Andy@LufbraUni Programming 1 03-30-2009 12:26 PM
Porting Serial port program from windows to linux farofeiro Programming 4 01-09-2009 11:40 AM
Issues porting c program from SUSE to Redhat v9.2 serconsult Programming 11 07-31-2008 03:28 AM
Porting DOS program to Linux. I have the C source code ... Micro420 Programming 8 04-19-2008 07:36 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:31 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration