/* gidsh.c Execute with setgid a Perl or shell script from /home/classes/csXYZ/bin. If the filename is NAME, then the Perl script NAME.pl or the shell script NAME.sh is executed. Hack: If neither NAME.pl nor NAME.sh exists in /home/classes/csXYZ/bin, then execute /home/classes/csXYZ/.bin/NAME.xx. */ #include #include #include #include #include #include #include #include #include #define MEMORY_LIMIT 8000000000 /* Limit on memory usage */ main (int argc, char *argv[]) { char *classes = "/home/classes"; char *prefix[] = {"bin", "bin", ".bin"}; char *suffix[] = {".pl", ".sh", ".xx" }; int nPrefix = sizeof(suffix) / sizeof(suffix[0]); struct group *group; char *base, *csXYZ, *name; struct rlimit rlim; int i; if ((base = rindex(argv[0],'/'))) /* Get base name of file */ base++; else base = argv[0]; if (! (group = getgrgid (getegid()))) { /* Get effective group name */ perror ("getgrgid failed"); exit (EXIT_FAILURE); } csXYZ = strdup (group->gr_name); /* Suppress TA/UCG suffix */ if (strstr (csXYZ, "ta")) *strstr (csXYZ, "ta") = 0; else if (strstr (csXYZ, "ucg")) *strstr (csXYZ, "ucg") = 0; else { fprintf (stderr, "invalid group: %s\n", csXYZ); exit (EXIT_FAILURE); } if (getrlimit (RLIMIT_AS, &rlim) < 0) { /* Get limits on memory */ perror ("getrlimit failed"); exit (EXIT_FAILURE); } if (rlim.rlim_max > MEMORY_LIMIT) { // Get limits on memory rlim.rlim_max = MEMORY_LIMIT; rlim.rlim_cur = MEMORY_LIMIT; if (setrlimit (RLIMIT_AS, &rlim) < 0) { perror ("setrlimit failed"); exit (EXIT_FAILURE); } } for (i = 0; i < nPrefix; i++) { name = malloc (strlen(classes) + strlen(csXYZ) + strlen(prefix[i]) + strlen(base) + strlen(suffix[i]) + 4); /* Three slashed plus a null */ sprintf (name,"%s/%s/%s/%s%s", classes, csXYZ, prefix[i], base, suffix[i]); execv (name, argv); } fprintf (stderr, "%s: exec failed\n", base); return(-1); }