include aculib in cleanup
[unix-history] / usr / src / usr.bin / passwd / chsh.sh
CommitLineData
9f52e30a
SL
1#ifndef lint
2static char *sccsid = "@(#)chsh.sh 4.5 (Berkeley) %G%";
3#endif
4
854c8e85
BJ
5/*
6 * chsh
7 */
8#include <stdio.h>
9#include <signal.h>
10#include <pwd.h>
9f52e30a
SL
11#include <sys/file.h>
12#include <time.h>
13#include <resource.h>
854c8e85
BJ
14
15char passwd[] = "/etc/passwd";
16char temp[] = "/etc/ptmp";
17struct passwd *pwd;
18struct passwd *getpwent();
19int endpwent();
20char *crypt();
21char *getpass();
9f52e30a 22char *strcat();
854c8e85
BJ
23char buf[BUFSIZ];
24
25main(argc, argv)
9f52e30a 26register char *argv[];
854c8e85 27{
9f52e30a
SL
28 register int u, fd;
29 register FILE *tf;
854c8e85 30
9f52e30a 31 if (argc < 2 || argc > 3) {
1f096eb2 32 printf("Usage: chsh user [ /bin/csh ]\n");
9f52e30a 33 exit(1);
854c8e85
BJ
34 }
35 if (argc == 2)
36 argv[2] = "";
9f52e30a
SL
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 );
78ffcf9e
BJ
51 exit(1);
52 }
9f52e30a
SL
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) {
854c8e85 62 u = getuid();
9f52e30a 63 if (u!=0 && u != pwd->pw_uid) {
854c8e85 64 printf("Permission denied.\n");
9f52e30a 65 exit(1);
854c8e85 66 }
9f52e30a 67 break;
854c8e85 68 }
9f52e30a 69 }
854c8e85 70 endpwent();
854c8e85 71
9f52e30a
SL
72 signal(SIGHUP, SIG_IGN);
73 signal(SIGINT, SIG_IGN);
74 signal(SIGQUIT, SIG_IGN);
75 signal(SIGTSTP, SIG_IGN);
76 if ((fd = open(temp, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
854c8e85 77 printf("Temporary file busy -- try again\n");
9f52e30a 78 exit(1);
854c8e85 79 }
9f52e30a
SL
80 if ((tf=fdopen(fd, "w")) == NULL) {
81 printf("Absurd fdopen failure - seek help\n");
82 goto out;
854c8e85 83 }
9f52e30a
SL
84 /*
85 * Copy passwd to temp, replacing matching lines
86 * with new shell.
87 */
88 while ((pwd=getpwent()) != NULL) {
89 if (strcmp(pwd->pw_name, argv[1]) == 0) {
854c8e85 90 u = getuid();
9f52e30a 91 if (u != 0 && u != pwd->pw_uid) {
854c8e85
BJ
92 printf("Permission denied.\n");
93 goto out;
94 }
95 pwd->pw_shell = argv[2];
96 }
9f52e30a
SL
97 if (strcmp(pwd->pw_shell, "/bin/sh") == 0)
98 pwd->pw_shell = "";
99 fprintf(tf, "%s:%s:%d:%d:%s:%s:%s\n"
100 , pwd->pw_name
101 , pwd->pw_passwd
102 , pwd->pw_uid
103 , pwd->pw_gid
104 , pwd->pw_gecos
105 , pwd->pw_dir
106 , pwd->pw_shell
107 );
854c8e85
BJ
108 }
109 endpwent();
9f52e30a
SL
110 if (rename(temp, passwd) < 0) {
111 fprintf(stderr, "chsh: "); perror("rename");
112 out:
113 unlink(temp);
114 exit(1);
854c8e85 115 }
9f52e30a
SL
116 fclose(tf);
117 exit(0);
118}
854c8e85 119
9f52e30a
SL
120unlimit(lim)
121{
122 struct rlimit rlim;
854c8e85 123
9f52e30a
SL
124 rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
125 setrlimit(lim, &rlim);
854c8e85 126}