(no message)
[unix-history] / usr / src / usr.bin / passwd / chsh.sh
CommitLineData
9f52e30a 1#ifndef lint
fb8f0ff2 2static char *sccsid = "@(#)chsh.sh 4.7 (Berkeley) %G%";
9f52e30a
SL
3#endif
4
854c8e85
BJ
5/*
6 * chsh
7 */
8#include <stdio.h>
9#include <signal.h>
10#include <pwd.h>
9f52e30a 11#include <sys/file.h>
840fc587
SL
12#include <sys/time.h>
13#include <sys/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);
fb8f0ff2 76 (void) umask(0);
9f52e30a 77 if ((fd = open(temp, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
854c8e85 78 printf("Temporary file busy -- try again\n");
9f52e30a 79 exit(1);
854c8e85 80 }
9f52e30a
SL
81 if ((tf=fdopen(fd, "w")) == NULL) {
82 printf("Absurd fdopen failure - seek help\n");
83 goto out;
854c8e85 84 }
9f52e30a
SL
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) {
854c8e85 91 u = getuid();
9f52e30a 92 if (u != 0 && u != pwd->pw_uid) {
854c8e85
BJ
93 printf("Permission denied.\n");
94 goto out;
95 }
96 pwd->pw_shell = argv[2];
97 }
9f52e30a
SL
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 );
854c8e85
BJ
109 }
110 endpwent();
9f52e30a
SL
111 if (rename(temp, passwd) < 0) {
112 fprintf(stderr, "chsh: "); perror("rename");
113 out:
114 unlink(temp);
115 exit(1);
854c8e85 116 }
9f52e30a
SL
117 fclose(tf);
118 exit(0);
119}
854c8e85 120
9f52e30a
SL
121unlimit(lim)
122{
123 struct rlimit rlim;
854c8e85 124
9f52e30a
SL
125 rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
126 setrlimit(lim, &rlim);
854c8e85 127}