home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / cli / su.lha / su / su.c < prev    next >
C/C++ Source or Header  |  1995-11-04  |  5KB  |  168 lines

  1. /* su.c */
  2.  
  3. /*-------------------------------------------------------------
  4. ** Program to do the equivilant of the *IX su command (Substitute User).
  5. ** If 1 argument is given (the userid), an attempt will be made to create
  6. ** a new shell under the new userid's uid. If the argument is the userid
  7. ** "root" (the superuser), or if there are no arguments given (in which case
  8. ** it defaults to "root"), the su program will check to see if the current
  9. ** user is a member of the group root (either primary or secondary).
  10. **        If the user is not in the group root, the program will return
  11. ** unsuccessfully.
  12. **    Next the password of the new user is requested, if the password matches
  13. ** the password of the supplied userid, then a new shell is spawned with the
  14. ** new user's uid, and the su program returns, and so does not wait for the
  15. ** other shell to return. Failed/Successfull attempts at su may/may not be
  16. ** logged in the multiuser.log file. This is handled my the multiuser.server,
  17. ** so it depends on your config file.
  18. **    © 1995 Chris Mc Carthy.
  19. **
  20. **    email:     cmccarth@icl.rtc-cork.ie        (Try this first, though sometimes
  21. **                                                         our /var partition fills up with
  22. **                                                         coredumps from the mailer :-(  )
  23. **                cmccarth@dullahan.rtc-cork.ie (mailer not configured yet, new system)
  24. **                atoz@nether.net                    (Safest, but may take a while to reply)
  25. **                atoz@mayhem.inferno.net
  26. **
  27. **    smail:    Chris Mc Carthy
  28. **                Castlepark
  29. **                Kinsale
  30. **                Co. Cork
  31. **                Ireland.
  32. **
  33. **    IRC:        AtoZ on #hack, #amiga, #wasteland (Mainly on the Undernet).
  34. **
  35. **
  36. **--------------------------------------------------------------
  37. */
  38.  
  39.  
  40.  
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44.  
  45. #include <libraries/multiuser.h>
  46. #include <libraries/dos.h>
  47. #include <proto/exec.h>
  48. #include <proto/dos.h>
  49. #include <proto/multiuser.h>
  50. #include <utility/tagitem.h>
  51.  
  52. /* Minimum library versions */
  53. #define DOSVER            36
  54. #define MULTIUSERVER    39
  55.  
  56. #define NEWSHELL        "NewShell"
  57. #define ROOTUSERID    "root"        /* UserID of the super-user */
  58.  
  59. void cleanUp(char *str, int rc);            /* Shutdown libs etc, and exit */
  60. int main(int argc, char *argv[]);
  61.  
  62. struct muBase *muBase;
  63. struct DosBase *DosBase;
  64.  
  65. struct muExtOwner *extOwner;        /* Info about user attempting to su */
  66.  
  67. main(int argc, char *argv[])
  68. {
  69.     STRPTR suUserID;                    /* Try to su to this user-id */
  70.     BOOL inRootGroup = FALSE;        /* primary or secondary group = root group */
  71.     int i;
  72.  
  73.     /* Check command line arguments */
  74.  
  75.     if (argc > 2)                /* Invalid arg count */
  76.         cleanUp("Usage: su <user-id>", ERROR_TOO_MANY_ARGS);
  77.     else if (argc == 2)        /* su to a non-superuser */
  78.         suUserID = argv[1];
  79.     else                            /* su to super-user (root) */
  80.         suUserID = ROOTUSERID;
  81.  
  82.  
  83.  
  84.     /* Open libraries */
  85.  
  86.     if (!(muBase = (struct muBase *) OpenLibrary (MULTIUSERNAME, MULTIUSERVER)))
  87.         cleanUp("Cant open multiuser.library", ERROR_INVALID_RESIDENT_LIBRARY);
  88.  
  89.     if (!(DosBase = (struct DosBase *) OpenLibrary (DOSNAME, DOSVER)))
  90.         cleanUp("Cant open dos.library", ERROR_INVALID_RESIDENT_LIBRARY);
  91.  
  92.  
  93.  
  94.     /* Get gid and sgid's of current user */
  95.  
  96.     extOwner = muGetTaskExtOwner(NULL);
  97.     if (!extOwner)
  98.         cleanUp("Out of memory.", ERROR_NO_FREE_STORE);
  99.  
  100.  
  101.     /* If attempting to su to root, so check to see if the user is in the
  102.         group root, (either primary or secondary member). */
  103.  
  104.     if (!strcmp(suUserID, ROOTUSERID)) {
  105.  
  106.         /* Check primary group */
  107.         if (extOwner->gid != muROOT_GID) {
  108.  
  109.             /* Check secondary groups */
  110.             for (i = 0; i < extOwner->NumSecGroups; i++)
  111.                 if (muSecGroups(extOwner)[i] == muROOT_GID) {
  112.                     inRootGroup = TRUE;    /* User is in root group */
  113.                     break;
  114.                 }
  115.  
  116.                 /* User not in root gruop */
  117.             if (!inRootGroup)
  118.                 cleanUp("Not in correct group to su to root", RETURN_WARN);
  119.         }
  120.  
  121.     }
  122.  
  123.  
  124.     /* ok, now if correct password supplied, su successfully. */
  125.  
  126.     if (!muLogin(muT_UserID, (ULONG) suUserID, TAG_DONE))
  127.         /* Incorrect password. */
  128.         cleanUp("Sorry.", RETURN_WARN);
  129.  
  130.  
  131.     /* Now start new shell with the new uid */
  132.     /* This will spawn off a new process, and this program will not wait for
  133.     ** the shell to return */
  134.  
  135.     if (!Execute(NEWSHELL,0,0))
  136.         cleanUp("Could not open new shell", RETURN_FAIL);
  137.  
  138.  
  139.     /* logout and return to the original shell */
  140.  
  141.     muLogout(muT_Quiet, TRUE, TAG_DONE);
  142.  
  143.     cleanUp("", RETURN_OK);
  144.  
  145. }
  146.  
  147. /*-----------------------------------
  148. ** Closedown, shut libs, and free allocated memory.
  149. ** Exit with the supplied return code
  150. **----------------------------------*/
  151.  
  152. void cleanUp(char *str, int rc)
  153. {
  154.  
  155.     if (extOwner)
  156.         muFreeExtOwner(extOwner);
  157.  
  158.     /* Since using >= v36, no need to check for NULL library pointers */
  159.     CloseLibrary((struct Library *)muBase);
  160.     CloseLibrary((struct Library *)DosBase);
  161.  
  162.     if (strcmp(str, ""))
  163.         puts(str);
  164.  
  165.     exit(rc);
  166.  
  167. }
  168.