/* Copyright (c) 1991 by Oracle Corporation */ /* NAME osh.c - DESCRIPTION PUBLIC FUNCTION(S) PRIVATE FUNCTION(S) RETURNS NOTES MODIFIED (MM/DD/YY) kaghevli 02/22/93 - Creation */ #ifdef RCSID static char *RCSid = "$Header: osh.c,v 1.1 93/02/22 23:33:07 KAGHEVLI: Exp $ osh.c Copyr (c) 1986 Oracle"; #endif /* RCSID */ /* ** Copyright (c) 1986 by Oracle Corporation ** ** osh - Routine to modify a user's ulimit ** ** Under UNIX the largest negating factor for large database is ** the process's "ulimit" parameter. Currently this only can be reset ** by the "super-user". This program needs to be run with the ownership ** of root and the "set uid" bit 'on'. The recommended mode of this program ** 4711 (-rws--x--x) which only allows this program to be "executed" but ** not copied. It raises the ulimit to a theoretical maximum and then ** "exec's" the shell specified in its name. "osh" will exec "sh", "ocsh" ** will exec "csh", etc. If the program is run by anybody other than the ** super-user, it automatically resets the program's uid to that of the ** person executing "osh" so as not to leave the user with unauthorized ** privelages. ** ** PLEASE NOTE: Any program with a set uid bit set is a POTENTIAL security ** problem and needs to be carefully controlled. ** ** Written: ** 11/01/84 Abbajay ** Modified: ** 07/20/86 Abbajay - Added optional "SHELL" variable lookup. ** 02/22/89 Andres - Added -l flag to print current ulimit. ** 02/22/92 jtellez - modified for sequent to change scheduling. ** ** Compile: cc -O osh.c -o osh ** Compile for Sequent: cc -O osh.c -o osh -lseq ** Install: with set uid root (4711) */ #include #include #define NEWLIMIT 2113674 /* define newlimit for upping ulimit */ #define DEFAULT_SHELL "/bin/sh" /* define deault shell */ #ifdef _SEQUENT_ /* Sequent only includes & defines */ # include # include # define USAGE "osh [-l] [-a] [-p] \n -l Prints the current ulimit.\n -a Disables Priority Aging.\n -p Disables Preemption.\n" #else # define USAGE "osh [-l]\n" #endif /* _SEQUENT_ */ char error_buffer[512]; char *getenv(); main(argc, argv, envp) int argc; char **argv; char **envp; { register char *cmd; /* command to execute */ register long newlimit=NEWLIMIT; /* define newlimit for upping ulimit */ char *shell; register int i; char *nargv[4096]; long ulimit(), oldlimit; char c, *op = "lap"; extern char *optarg; extern int optind; while ((c = getopt(argc, argv, op)) != -1) switch (c) { case 'l': if ( (oldlimit = ulimit(1)) == -1) { sprintf(error_buffer,"%s: Couldn't get process ulimit.\n",argv[0]); perror(error_buffer); exit(-1); } else { printf("%d\n",oldlimit); exit(0); } break; #ifdef _SEQUENT_ case 'a': if (proc_ctl(PROC_PRIOAGE, 0, 0)) { sprintf(error_buffer, "%s: Couldn't disable priority aging.\n",argv[0]); perror(error_buffer); exit(-1); } break; case 'p': if (proc_ctl(PROC_NOPREEMPT, 0, 1)) { sprintf(error_buffer, "%s: Couldn't disable process preemption.\n",argv[0]); perror(error_buffer); exit(-1); } break; #endif /* _SEQUENT_ */ default: sprintf(error_buffer,"%s\n", USAGE); perror(error_buffer); exit(1); break; } if(ulimit(2, newlimit) == -1) { if (errno == EPERM) { (void) fprintf(stderr, "%s: Can't raise ulimit. The mode of %s should be 4711 and owned by root.\n", argv[0], argv[0]); } else perror(argv[0]); exit(-1); } if(setuid(getuid())) /* set uid back to original */ { perror(argv[0]); exit(-1); } if (argc == optind) { shell = nargv[0] = (nargv[0] = getenv("SHELL")) ? nargv[0] : DEFAULT_SHELL; nargv[1] = NULL; if (execve(shell, nargv, envp)) { perror(argv[0]); exit(-1); } } else { i=optind; while (argv[i] != NULL) { nargv[i-optind] = argv[i]; i++; } nargv[i]=NULL; if (execvp(nargv[0], nargv)) { if (errno != ENOTTY) /* abort on any other error */ { perror(argv[0]); exit(-1); } } } exit(0); } /* END PROGRAM */