|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)chsh.c 4.7 (Berkeley) 7/10/83";
3: #endif
4:
5: /*
6: * chsh
7: */
8: #include <stdio.h>
9: #include <signal.h>
10: #include <pwd.h>
11: #include <sys/file.h>
12: #include <sys/time.h>
13: #include <sys/resource.h>
14:
15: char passwd[] = "/etc/passwd";
16: char temp[] = "/etc/ptmp";
17: struct passwd *pwd;
18: struct passwd *getpwent();
19: int endpwent();
20: char *crypt();
21: char *getpass();
22: char *strcat();
23: char buf[BUFSIZ];
24:
25: main(argc, argv)
26: register char *argv[];
27: {
28: register int u, fd;
29: register FILE *tf;
30:
31: if (argc < 2 || argc > 3) {
32: printf("Usage: chsh user [ /bin/csh ]\n");
33: exit(1);
34: }
35: if (argc == 2)
36: argv[2] = "";
37: else {
38: if (argv[2][0] != '/')
39: argv[2] = strcat(
40: "/bin/\0 12345678901234567890123456789", argv[2]);
41: if (strcmp(argv[2], "/bin/csh") &&
42: strcmp(argv[2], "/bin/oldcsh") &&
43: strcmp(argv[2], "/bin/newcsh") &&
44: strcmp(argv[2], "/usr/new/csh") &&
45: /* and, for cretins who can't read the manual */
46: strcmp(argv[2], "/bin/sh") &&
47: getuid()) {
48: printf(
49: "Only /bin/csh may be specified\n"
50: );
51: exit(1);
52: }
53: if (access(argv[2], 1) < 0) {
54: printf("%s is not available\n", argv[2]);
55: exit(1);
56: }
57: }
58: unlimit(RLIMIT_CPU);
59: unlimit(RLIMIT_FSIZE);
60: while ((pwd=getpwent()) != NULL) {
61: if (strcmp(pwd->pw_name, argv[1]) == 0) {
62: u = getuid();
63: if (u!=0 && u != pwd->pw_uid) {
64: printf("Permission denied.\n");
65: exit(1);
66: }
67: break;
68: }
69: }
70: endpwent();
71:
72: signal(SIGHUP, SIG_IGN);
73: signal(SIGINT, SIG_IGN);
74: signal(SIGQUIT, SIG_IGN);
75: signal(SIGTSTP, SIG_IGN);
76: (void) umask(0);
77: if ((fd = open(temp, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
78: printf("Temporary file busy -- try again\n");
79: exit(1);
80: }
81: if ((tf=fdopen(fd, "w")) == NULL) {
82: printf("Absurd fdopen failure - seek help\n");
83: goto out;
84: }
85: /*
86: * Copy passwd to temp, replacing matching lines
87: * with new shell.
88: */
89: while ((pwd=getpwent()) != NULL) {
90: if (strcmp(pwd->pw_name, argv[1]) == 0) {
91: u = getuid();
92: if (u != 0 && u != pwd->pw_uid) {
93: printf("Permission denied.\n");
94: goto out;
95: }
96: pwd->pw_shell = argv[2];
97: }
98: if (strcmp(pwd->pw_shell, "/bin/sh") == 0)
99: pwd->pw_shell = "";
100: fprintf(tf, "%s:%s:%d:%d:%s:%s:%s\n"
101: , pwd->pw_name
102: , pwd->pw_passwd
103: , pwd->pw_uid
104: , pwd->pw_gid
105: , pwd->pw_gecos
106: , pwd->pw_dir
107: , pwd->pw_shell
108: );
109: }
110: endpwent();
111: if (rename(temp, passwd) < 0) {
112: fprintf(stderr, "chsh: "); perror("rename");
113: out:
114: unlink(temp);
115: exit(1);
116: }
117: fclose(tf);
118: exit(0);
119: }
120:
121: unlimit(lim)
122: {
123: struct rlimit rlim;
124:
125: rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
126: setrlimit(lim, &rlim);
127: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.