home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / tcl / tclX6.5c / src / tclXid.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  9.4 KB  |  332 lines

  1. /*
  2.  * tclXid.c --
  3.  *
  4.  * Tcl commands to access getuid, setuid, getgid, setgid and friends.
  5.  *---------------------------------------------------------------------------
  6.  * Copyright 1992 Karl Lehenbauer and Mark Diekhans.
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies.  Karl Lehenbauer and
  11.  * Mark Diekhans make no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without express or
  13.  * implied warranty.
  14.  *-----------------------------------------------------------------------------
  15.  * $Id: tclXid.c,v 2.0 1992/10/16 04:50:51 markd Rel $
  16.  *-----------------------------------------------------------------------------
  17.  */
  18.  
  19. #include "tclExtdInt.h"
  20.  
  21. /*
  22.  * Prototypes of internal functions.
  23.  */
  24. int
  25. UseridToUsernameResult _ANSI_ARGS_((Tcl_Interp *interp,
  26.                                     int         userId));
  27.  
  28. int
  29. UsernameToUseridResult _ANSI_ARGS_((Tcl_Interp *interp,
  30.                                     char       *userName));
  31.  
  32. int
  33. GroupidToGroupnameResult _ANSI_ARGS_((Tcl_Interp *interp,
  34.                                       int         groupId));
  35.  
  36. int
  37. GroupnameToGroupidResult _ANSI_ARGS_((Tcl_Interp *interp,
  38.                                       char       *groupName));
  39.  
  40.  
  41. /*
  42.  *-----------------------------------------------------------------------------
  43.  *
  44.  * Tcl_IdCmd --
  45.  *     Implements the TCL id command:
  46.  *
  47.  *        id user [name]
  48.  *        id convert user <name>
  49.  *
  50.  *        id userid [uid]
  51.  *        id convert userid <uid>
  52.  *
  53.  *        id group [name]
  54.  *        id convert group <name>
  55.  *
  56.  *        id groupid [gid]
  57.  *        id convert groupid <gid>
  58.  *
  59.  *        id process
  60.  *        id process parent
  61.  *        id process group
  62.  *        id process group set
  63.  *
  64.  *        id effective user
  65.  *        id effective userid
  66.  *
  67.  *        id effective group
  68.  *        id effective groupid
  69.  *
  70.  * Results:
  71.  *  Standard TCL results, may return the UNIX system error message.
  72.  *
  73.  *-----------------------------------------------------------------------------
  74.  */
  75.  
  76. static int
  77. UseridToUsernameResult (interp, userId)
  78.     Tcl_Interp *interp;
  79.     int         userId;
  80. {
  81.     struct passwd *pw = getpwuid (userId);
  82.     if (pw == NULL) {
  83.         char numBuf [32];
  84.  
  85.         sprintf (numBuf, "%d", userId);
  86.         Tcl_AppendResult (interp, "unknown user id: ", numBuf, (char *) NULL);
  87.         return TCL_ERROR;
  88.     }
  89.     strcpy (interp->result, pw->pw_name);
  90.     return TCL_OK;
  91. }
  92.  
  93. static int
  94. UsernameToUseridResult (interp, userName)
  95.     Tcl_Interp *interp;
  96.     char       *userName;
  97. {
  98.     struct passwd *pw = getpwnam (userName);
  99.     if (pw == NULL) {
  100.         Tcl_AppendResult (interp, "unknown user id: ", userName, 
  101.                           (char *) NULL);
  102.         return TCL_ERROR;
  103.     }
  104.     sprintf (interp->result, "%d", pw->pw_uid);
  105.     return TCL_OK;
  106. }
  107.  
  108. static int
  109. GroupidToGroupnameResult (interp, groupId)
  110.     Tcl_Interp *interp;
  111.     int         groupId;
  112. {
  113.     struct group *grp = getgrgid (groupId);
  114.     if (grp == NULL) {
  115.         char numBuf [32];
  116.  
  117.         sprintf (numBuf, "%d", groupId);
  118.         Tcl_AppendResult (interp, "unknown group id: ", numBuf, (char *) NULL);
  119.         return TCL_ERROR;
  120.     }
  121.     strcpy (interp->result, grp->gr_name);
  122.     return TCL_OK;
  123. }
  124.  
  125. static int
  126. GroupnameToGroupidResult (interp, groupName)
  127.     Tcl_Interp *interp;
  128.     char       *groupName;
  129. {
  130.     struct group *grp = getgrnam (groupName);
  131.     if (grp == NULL) {
  132.         Tcl_AppendResult (interp, "unknown group id: ", groupName,
  133.                           (char *) NULL);
  134.         return TCL_ERROR;
  135.     }
  136.     sprintf (interp->result, "%d", grp->gr_gid);
  137.     return TCL_OK;
  138. }
  139.  
  140. int
  141. Tcl_IdCmd (clientData, interp, argc, argv)
  142.     ClientData  clientData;
  143.     Tcl_Interp *interp;
  144.     int         argc;
  145.     char      **argv;
  146. {
  147.     struct passwd *pw;
  148.     struct group *grp;
  149.     int uid, gid;
  150.  
  151.     if (argc < 2) 
  152.         goto bad_args;
  153.  
  154.     /*
  155.      * If the first argument is "convert", handle the conversion.
  156.      */
  157.     if (STREQU (argv[1], "convert")) {
  158.         if (argc != 4) {
  159.             Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  160.                               " convert arg arg", (char *) NULL);
  161.             return TCL_ERROR;
  162.         }
  163.  
  164.         if (STREQU (argv[2], "user"))
  165.             return UsernameToUseridResult (interp, argv[3]);
  166.  
  167.         if (STREQU (argv[2], "userid")) {
  168.             if (Tcl_GetInt (interp, argv[3], &uid) != TCL_OK) 
  169.                 return TCL_ERROR;
  170.             return UseridToUsernameResult (interp, uid);
  171.         }
  172.  
  173.         if (STREQU (argv[2], "group"))
  174.             return GroupnameToGroupidResult (interp, argv[3]);
  175.  
  176.         if (STREQU (argv[2], "groupid")) {
  177.             if (Tcl_GetInt (interp, argv[3], &gid) != TCL_OK) return TCL_ERROR;
  178.             return GroupidToGroupnameResult (interp, gid);
  179.  
  180.         }
  181.         goto bad_three_arg;
  182.     }
  183.  
  184.     /*
  185.      * If the first argument is "effective", return the effective user ID,
  186.      * name, group ID or name.
  187.      */
  188.     if (STREQU (argv[1], "effective")) {
  189.         if (argc != 3) {
  190.             Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  191.                               " effective arg", (char *) NULL);
  192.             return TCL_ERROR;
  193.         }
  194.  
  195.         if (STREQU (argv[2], "user"))
  196.             return UseridToUsernameResult (interp, geteuid ());
  197.  
  198.         if (STREQU (argv[2], "userid")) {
  199.             sprintf (interp->result, "%d", geteuid ());
  200.             return TCL_OK;
  201.         }
  202.  
  203.         if (STREQU (argv[2], "group"))
  204.             return GroupidToGroupnameResult (interp, getegid ());
  205.  
  206.         if (STREQU (argv[2], "groupid")) {
  207.             sprintf (interp->result, "%d", getegid ());
  208.             return TCL_OK;
  209.         }
  210.         goto bad_three_arg;
  211.     }
  212.  
  213.     /*
  214.      * If the first argument is "process", return the process ID, parent's
  215.      * process ID, process group or set the process group depending on args.
  216.      */
  217.     if (STREQU (argv[1], "process")) {
  218.         if (argc == 2) {
  219.             sprintf (interp->result, "%d", getpid ());
  220.             return TCL_OK;
  221.         }
  222.  
  223.         if (STREQU (argv[2], "parent")) {
  224.             if (argc != 3) {
  225.                 Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  226.                                   " process parent", (char *) NULL);
  227.                 return TCL_ERROR;
  228.             }
  229.             sprintf (interp->result, "%d", getppid ());
  230.             return TCL_OK;
  231.         }
  232.         if (STREQU (argv[2], "group")) {
  233.             if (argc == 3) {
  234.                 sprintf (interp->result, "%d", getpgrp ());
  235.                 return TCL_OK;
  236.             }
  237.             if ((argc != 4) || !STREQU (argv[3], "set")) {
  238.                 Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  239.                                   " process group [set]", (char *) NULL);
  240.                 return TCL_ERROR;
  241.             }
  242.             setpgrp ();
  243.             return TCL_OK;
  244.         }
  245.         Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  246.                           " process [parent|group|group set]", (char *) NULL);
  247.         return TCL_ERROR;
  248.     }
  249.  
  250.     /*
  251.      * Handle setting or returning the user ID or group ID (by name or number).
  252.      */
  253.     if (argc > 3)
  254.         goto bad_args;
  255.  
  256.     if (STREQU (argv[1], "user")) {
  257.         if (argc == 2) {
  258.             return UseridToUsernameResult (interp, getuid ());
  259.         } else {
  260.             pw = getpwnam (argv[2]);
  261.             if (pw == NULL)
  262.                 goto name_doesnt_exist;
  263.             if (setuid (pw->pw_uid) < 0)
  264.                 goto cannot_set_name;
  265.             return TCL_OK;
  266.         }
  267.     }
  268.  
  269.     if (STREQU (argv[1], "userid")) {
  270.         if (argc == 2) {
  271.             sprintf (interp->result, "%d", getuid ());
  272.             return TCL_OK;
  273.         } else {
  274.             if (Tcl_GetInt (interp, argv[2], &uid) != TCL_OK)
  275.                 return TCL_ERROR;
  276.             if (setuid (uid) < 0) 
  277.                 goto cannot_set_name;
  278.             return TCL_OK;
  279.         }
  280.     }
  281.  
  282.     if (STREQU (argv[1], "group")) {
  283.         if (argc == 2) {
  284.             return GroupidToGroupnameResult (interp, getgid ());
  285.         } else {
  286.             grp = getgrnam (argv[2]);
  287.             if (grp == NULL) 
  288.                 goto name_doesnt_exist;
  289.             if (setgid (grp->gr_gid) < 0)
  290.                 goto cannot_set_name;
  291.             return TCL_OK;
  292.         }
  293.     }
  294.  
  295.     if (STREQU (argv[1], "groupid")) {
  296.         if (argc == 2) {
  297.             sprintf (interp->result, "%d", getgid ());
  298.             return TCL_OK;
  299.         } else {
  300.             if (Tcl_GetInt (interp, argv[2], &gid) != TCL_OK)
  301.                 return TCL_ERROR;
  302.             if (setgid (gid) < 0)
  303.                 goto cannot_set_name;
  304.             return TCL_OK;
  305.         }
  306.     }
  307.     Tcl_AppendResult (interp, "bad arg: ", argv [0], 
  308.                       " second arg must be convert, effective, process, ",
  309.                       "user, userid, group or groupid", (char *) NULL);
  310.     return TCL_ERROR;
  311.  
  312.  
  313.   bad_three_arg:
  314.     Tcl_AppendResult (interp, "bad arg: ", argv [0], ": ", argv[1],
  315.                       ": third arg must be user, userid, group or groupid",
  316.                       (char *) NULL);
  317.     return TCL_ERROR;
  318.   bad_args:
  319.     Tcl_AppendResult (interp, tclXWrongArgs, argv [0], " arg [arg..]",
  320.                       (char *) NULL);
  321.     return TCL_ERROR;
  322.  
  323.   name_doesnt_exist:
  324.     Tcl_AppendResult (interp, " \"", argv[2], "\" does not exists",
  325.                       (char *) NULL);
  326.     return TCL_ERROR;
  327.  
  328.   cannot_set_name:
  329.     interp->result = Tcl_UnixError (interp);
  330.     return TCL_ERROR;
  331. }
  332.