home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / tcl / tclx7_31.z / tclx7_31 / tcldev / tclX7.3a-p1 / src / tclXid.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-19  |  9.9 KB  |  351 lines

  1. /*
  2.  * tclXid.c --
  3.  *
  4.  * Tcl commands to access getuid, setuid, getgid, setgid and friends.
  5.  *---------------------------------------------------------------------------
  6.  * Copyright 1991-1993 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 3.0 1993/11/19 06:58:49 markd Rel $
  16.  *-----------------------------------------------------------------------------
  17.  */
  18.  
  19. #include "tclExtdInt.h"
  20.  
  21. /*
  22.  * Prototypes of internal functions.
  23.  */
  24. static int
  25. UseridToUsernameResult _ANSI_ARGS_((Tcl_Interp *interp,
  26.                                     int         userId));
  27.  
  28. static int
  29. UsernameToUseridResult _ANSI_ARGS_((Tcl_Interp *interp,
  30.                                     char       *userName));
  31.  
  32. static int
  33. GroupidToGroupnameResult _ANSI_ARGS_((Tcl_Interp *interp,
  34.                                       int         groupId));
  35.  
  36. static 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.     uid_t          uid = (uid_t) userId;
  82.     struct passwd *pw = getpwuid (userId);
  83.  
  84.     if ((pw == NULL) || ((int) uid != userId)) {
  85.         sprintf (interp->result, "unknown user id: %d", userId);
  86.         endpwent ();
  87.         return TCL_ERROR;
  88.     }
  89.     strcpy (interp->result, pw->pw_name);
  90.     endpwent ();
  91.     return TCL_OK;
  92. }
  93.  
  94. static int
  95. UsernameToUseridResult (interp, userName)
  96.     Tcl_Interp *interp;
  97.     char       *userName;
  98. {
  99.     struct passwd *pw = getpwnam (userName);
  100.  
  101.     if (pw == NULL) {
  102.         Tcl_AppendResult (interp, "unknown user id: ", userName, 
  103.                           (char *) NULL);
  104.         endpwent ();
  105.         return TCL_ERROR;
  106.     }
  107.     sprintf (interp->result, "%d", pw->pw_uid);
  108.     endpwent ();
  109.     return TCL_OK;
  110. }
  111.  
  112. static int
  113. GroupidToGroupnameResult (interp, groupId)
  114.     Tcl_Interp *interp;
  115.     int         groupId;
  116. {
  117.     gid_t         gid = (gid_t) groupId;
  118.     struct group *grp = getgrgid (groupId);
  119.  
  120.     if ((grp == NULL) || ((int) gid != groupId)) {
  121.         sprintf (interp->result, "unknown group id: %d", groupId);
  122.         endgrent ();
  123.         return TCL_ERROR;
  124.     }
  125.     strcpy (interp->result, grp->gr_name);
  126.     endgrent ();
  127.     return TCL_OK;
  128. }
  129.  
  130. static int
  131. GroupnameToGroupidResult (interp, groupName)
  132.     Tcl_Interp *interp;
  133.     char       *groupName;
  134. {
  135.     struct group *grp = getgrnam (groupName);
  136.     if (grp == NULL) {
  137.         Tcl_AppendResult (interp, "unknown group id: ", groupName,
  138.                           (char *) NULL);
  139.         return TCL_ERROR;
  140.     }
  141.     sprintf (interp->result, "%d", grp->gr_gid);
  142.     return TCL_OK;
  143. }
  144.  
  145. int
  146. Tcl_IdCmd (clientData, interp, argc, argv)
  147.     ClientData  clientData;
  148.     Tcl_Interp *interp;
  149.     int         argc;
  150.     char      **argv;
  151. {
  152.     struct passwd *pw;
  153.     struct group *grp;
  154.     int           uid, gid;
  155.     pid_t         pid;
  156.  
  157.     if (argc < 2) 
  158.         goto bad_args;
  159.  
  160.     /*
  161.      * If the first argument is "convert", handle the conversion.
  162.      */
  163.     if (STREQU (argv[1], "convert")) {
  164.         if (argc != 4) {
  165.             Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  166.                               " convert arg arg", (char *) NULL);
  167.             return TCL_ERROR;
  168.         }
  169.  
  170.         if (STREQU (argv[2], "user"))
  171.             return UsernameToUseridResult (interp, argv[3]);
  172.  
  173.         if (STREQU (argv[2], "userid")) {
  174.             if (Tcl_GetInt (interp, argv[3], &uid) != TCL_OK) 
  175.                 return TCL_ERROR;
  176.             return UseridToUsernameResult (interp, uid);
  177.         }
  178.  
  179.         if (STREQU (argv[2], "group"))
  180.             return GroupnameToGroupidResult (interp, argv[3]);
  181.  
  182.         if (STREQU (argv[2], "groupid")) {
  183.             if (Tcl_GetInt (interp, argv[3], &gid) != TCL_OK)
  184.                 return TCL_ERROR;
  185.             return GroupidToGroupnameResult (interp, gid);
  186.  
  187.         }
  188.         goto bad_three_arg;
  189.     }
  190.  
  191.     /*
  192.      * If the first argument is "effective", return the effective user ID,
  193.      * name, group ID or name.
  194.      */
  195.     if (STREQU (argv[1], "effective")) {
  196.         if (argc != 3) {
  197.             Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  198.                               " effective arg", (char *) NULL);
  199.             return TCL_ERROR;
  200.         }
  201.  
  202.         if (STREQU (argv[2], "user"))
  203.             return UseridToUsernameResult (interp, geteuid ());
  204.  
  205.         if (STREQU (argv[2], "userid")) {
  206.             sprintf (interp->result, "%d", geteuid ());
  207.             return TCL_OK;
  208.         }
  209.  
  210.         if (STREQU (argv[2], "group"))
  211.             return GroupidToGroupnameResult (interp, getegid ());
  212.  
  213.         if (STREQU (argv[2], "groupid")) {
  214.             sprintf (interp->result, "%d", getegid ());
  215.             return TCL_OK;
  216.         }
  217.         goto bad_three_arg;
  218.     }
  219.  
  220.     /*
  221.      * If the first argument is "process", return the process ID, parent's
  222.      * process ID, process group or set the process group depending on args.
  223.      */
  224.     if (STREQU (argv[1], "process")) {
  225.         if (argc == 2) {
  226.             sprintf (interp->result, "%d", getpid ());
  227.             return TCL_OK;
  228.         }
  229.  
  230.         if (STREQU (argv[2], "parent")) {
  231.             if (argc != 3) {
  232.                 Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  233.                                   " process parent", (char *) NULL);
  234.                 return TCL_ERROR;
  235.             }
  236.             sprintf (interp->result, "%d", getppid ());
  237.             return TCL_OK;
  238.         }
  239.         if (STREQU (argv[2], "group")) {
  240.             if (argc == 3) {
  241.                 sprintf (interp->result, "%d", getpgrp ());
  242.                 return TCL_OK;
  243.             }
  244.             if ((argc != 4) || !STREQU (argv[3], "set")) {
  245.                 Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  246.                                   " process group ?set?", (char *) NULL);
  247.                 return TCL_ERROR;
  248.             }
  249. #ifdef HAVE_SETPGID
  250.             pid = getpid ();
  251.             setpgid (pid, pid);
  252. #else
  253.             setpgrp ();
  254. #endif
  255.             return TCL_OK;
  256.         }
  257.         Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  258.                           " process ?parent|group|group? ?set?",
  259.                           (char *) NULL);
  260.         return TCL_ERROR;
  261.     }
  262.  
  263.     /*
  264.      * Handle setting or returning the user ID or group ID (by name or number).
  265.      */
  266.     if (argc > 3)
  267.         goto bad_args;
  268.  
  269.     if (STREQU (argv[1], "user")) {
  270.         if (argc == 2) {
  271.             return UseridToUsernameResult (interp, getuid ());
  272.         } else {
  273.             pw = getpwnam (argv[2]);
  274.             if (pw == NULL)
  275.                 goto name_doesnt_exist;
  276.             if (setuid (pw->pw_uid) < 0)
  277.                 goto cannot_set_name;
  278.             endpwent ();
  279.             return TCL_OK;
  280.         }
  281.     }
  282.  
  283.     if (STREQU (argv[1], "userid")) {
  284.         if (argc == 2) {
  285.             sprintf (interp->result, "%d", getuid ());
  286.             return TCL_OK;
  287.         } else {
  288.             if (Tcl_GetInt (interp, argv[2], &uid) != TCL_OK)
  289.                 return TCL_ERROR;
  290.             if (setuid ((uid_t) uid) < 0) 
  291.                 goto cannot_set_name;
  292.             return TCL_OK;
  293.         }
  294.     }
  295.  
  296.     if (STREQU (argv[1], "group")) {
  297.         if (argc == 2) {
  298.             return GroupidToGroupnameResult (interp, getgid ());
  299.         } else {
  300.             grp = getgrnam (argv[2]);
  301.             if (grp == NULL)
  302.                 goto name_doesnt_exist;
  303.             if (setgid (grp->gr_gid) < 0)
  304.                 goto cannot_set_name;
  305.             endgrent ();
  306.             return TCL_OK;
  307.         }
  308.     }
  309.  
  310.     if (STREQU (argv[1], "groupid")) {
  311.         if (argc == 2) {
  312.             sprintf (interp->result, "%d", getgid ());
  313.             return TCL_OK;
  314.         } else {
  315.             if (Tcl_GetInt (interp, argv[2], &gid) != TCL_OK)
  316.                 return TCL_ERROR;
  317.             if (setgid ((gid_t) gid) < 0)
  318.                 goto cannot_set_name;
  319.             return TCL_OK;
  320.         }
  321.     }
  322.     Tcl_AppendResult (interp, "bad arg: ", argv [0], 
  323.                       " second arg must be convert, effective, process, ",
  324.                       "user, userid, group or groupid", (char *) NULL);
  325.     return TCL_ERROR;
  326.  
  327.  
  328.   bad_three_arg:
  329.     Tcl_AppendResult (interp, "bad arg: ", argv [0], ": ", argv[1],
  330.                       ": third arg must be user, userid, group or groupid",
  331.                       (char *) NULL);
  332.     return TCL_ERROR;
  333.   bad_args:
  334.     Tcl_AppendResult (interp, tclXWrongArgs, argv [0], " arg ?arg..?",
  335.                       (char *) NULL);
  336.     return TCL_ERROR;
  337.  
  338.   name_doesnt_exist:
  339.     Tcl_AppendResult (interp, " \"", argv[2], "\" does not exists",
  340.                       (char *) NULL);
  341.     endpwent ();
  342.     endgrent ();
  343.     return TCL_ERROR;
  344.  
  345.   cannot_set_name:
  346.     interp->result = Tcl_PosixError (interp);
  347.     endpwent ();
  348.     endgrent ();
  349.     return TCL_ERROR;
  350. }
  351.