home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 10
/
aminetcdnumber101996.iso
/
Aminet
/
util
/
cli
/
su.lha
/
su
/
su.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-04
|
5KB
|
168 lines
/* su.c */
/*-------------------------------------------------------------
** Program to do the equivilant of the *IX su command (Substitute User).
** If 1 argument is given (the userid), an attempt will be made to create
** a new shell under the new userid's uid. If the argument is the userid
** "root" (the superuser), or if there are no arguments given (in which case
** it defaults to "root"), the su program will check to see if the current
** user is a member of the group root (either primary or secondary).
** If the user is not in the group root, the program will return
** unsuccessfully.
** Next the password of the new user is requested, if the password matches
** the password of the supplied userid, then a new shell is spawned with the
** new user's uid, and the su program returns, and so does not wait for the
** other shell to return. Failed/Successfull attempts at su may/may not be
** logged in the multiuser.log file. This is handled my the multiuser.server,
** so it depends on your config file.
** © 1995 Chris Mc Carthy.
**
** email: cmccarth@icl.rtc-cork.ie (Try this first, though sometimes
** our /var partition fills up with
** coredumps from the mailer :-( )
** cmccarth@dullahan.rtc-cork.ie (mailer not configured yet, new system)
** atoz@nether.net (Safest, but may take a while to reply)
** atoz@mayhem.inferno.net
**
** smail: Chris Mc Carthy
** Castlepark
** Kinsale
** Co. Cork
** Ireland.
**
** IRC: AtoZ on #hack, #amiga, #wasteland (Mainly on the Undernet).
**
**
**--------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libraries/multiuser.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/multiuser.h>
#include <utility/tagitem.h>
/* Minimum library versions */
#define DOSVER 36
#define MULTIUSERVER 39
#define NEWSHELL "NewShell"
#define ROOTUSERID "root" /* UserID of the super-user */
void cleanUp(char *str, int rc); /* Shutdown libs etc, and exit */
int main(int argc, char *argv[]);
struct muBase *muBase;
struct DosBase *DosBase;
struct muExtOwner *extOwner; /* Info about user attempting to su */
main(int argc, char *argv[])
{
STRPTR suUserID; /* Try to su to this user-id */
BOOL inRootGroup = FALSE; /* primary or secondary group = root group */
int i;
/* Check command line arguments */
if (argc > 2) /* Invalid arg count */
cleanUp("Usage: su <user-id>", ERROR_TOO_MANY_ARGS);
else if (argc == 2) /* su to a non-superuser */
suUserID = argv[1];
else /* su to super-user (root) */
suUserID = ROOTUSERID;
/* Open libraries */
if (!(muBase = (struct muBase *) OpenLibrary (MULTIUSERNAME, MULTIUSERVER)))
cleanUp("Cant open multiuser.library", ERROR_INVALID_RESIDENT_LIBRARY);
if (!(DosBase = (struct DosBase *) OpenLibrary (DOSNAME, DOSVER)))
cleanUp("Cant open dos.library", ERROR_INVALID_RESIDENT_LIBRARY);
/* Get gid and sgid's of current user */
extOwner = muGetTaskExtOwner(NULL);
if (!extOwner)
cleanUp("Out of memory.", ERROR_NO_FREE_STORE);
/* If attempting to su to root, so check to see if the user is in the
group root, (either primary or secondary member). */
if (!strcmp(suUserID, ROOTUSERID)) {
/* Check primary group */
if (extOwner->gid != muROOT_GID) {
/* Check secondary groups */
for (i = 0; i < extOwner->NumSecGroups; i++)
if (muSecGroups(extOwner)[i] == muROOT_GID) {
inRootGroup = TRUE; /* User is in root group */
break;
}
/* User not in root gruop */
if (!inRootGroup)
cleanUp("Not in correct group to su to root", RETURN_WARN);
}
}
/* ok, now if correct password supplied, su successfully. */
if (!muLogin(muT_UserID, (ULONG) suUserID, TAG_DONE))
/* Incorrect password. */
cleanUp("Sorry.", RETURN_WARN);
/* Now start new shell with the new uid */
/* This will spawn off a new process, and this program will not wait for
** the shell to return */
if (!Execute(NEWSHELL,0,0))
cleanUp("Could not open new shell", RETURN_FAIL);
/* logout and return to the original shell */
muLogout(muT_Quiet, TRUE, TAG_DONE);
cleanUp("", RETURN_OK);
}
/*-----------------------------------
** Closedown, shut libs, and free allocated memory.
** Exit with the supplied return code
**----------------------------------*/
void cleanUp(char *str, int rc)
{
if (extOwner)
muFreeExtOwner(extOwner);
/* Since using >= v36, no need to check for NULL library pointers */
CloseLibrary((struct Library *)muBase);
CloseLibrary((struct Library *)DosBase);
if (strcmp(str, ""))
puts(str);
exit(rc);
}