1: char *sccsid[] = "@(#)chsh.c 2.4";
2: /*
3: * chsh
4: */
5: #include <whoami.h>
6: #include <stdio.h>
7: #include <signal.h>
8: #include <pwd.h>
9:
10: #define NSHELLS 2 /* Number of shells in valid list */
11: #define SMLROOT /* Not enough space in /etc for duplicate of passwd */
12:
13: char pwfile[] = "/etc/passwd";
14: #ifndef SMLROOT
15: char temp[] = "/etc/ptmp";
16: #else
17: char temp[] = "/tmp/pwdXXXXXX";
18: #endif
19:
20: char *shells[NSHELLS] = { /* First in list is default shell */
21: "/bin/csh",
22: "/bin/sh"
23: };
24: char *defsh;
25: struct passwd *pwd;
26: struct passwd *getpwent();
27: int endpwent();
28: char *crypt();
29: char *getpass();
30: char buf[BUFSIZ];
31:
32: main(argc, argv)
33: char *argv[];
34: {
35: int u,fi,fo;
36: int i;
37: FILE *tf;
38: #ifdef UCB_GRPMAST
39: int g;
40: #endif
41:
42: defsh = shells[0];
43: if(argc < 2 || argc > 3) {
44: printf("Usage: chsh user [ shell ]\n");
45: goto bex;
46: }
47: if (argc == 2)
48: argv[2] = defsh;
49: u = getuid();
50: #ifdef UCB_GRPMAST
51: g = getgid();
52: #endif
53: if (u) {
54: for (i=0; i<NSHELLS; i++)
55: if (!strcmp(argv[2], shells[i]))
56: goto doit;
57: printf("Invalid shell. Valid shells are:\n");
58: for(i=0; i<NSHELLS; i++)
59: printf("\t%s\n", shells[i]);
60: exit(1);
61: }
62:
63: doit:
64: if (!strcmp(argv[2], defsh))
65: argv[2] = "";
66: while((pwd=getpwent()) != NULL){
67: if(strcmp(pwd->pw_name,argv[1]) == 0){
68: if(u!=0 && u != pwd->pw_uid
69: #ifdef UCB_GRPMAST
70: && !(u==g && g==pwd->pw_gid)
71: #endif
72: ){
73: printf("Permission denied.\n");
74: goto bex;
75: }
76: if (u) {
77: if (*pwd->pw_shell == '\0')
78: pwd->pw_shell = defsh;
79: for (i=0; i<NSHELLS; i++)
80: if (!strcmp(pwd->pw_shell, shells[i]))
81: goto ok;
82: printf("Can't change shell for %s\n", pwd->pw_name);
83: }
84: ok:
85: break;
86: }
87: }
88: endpwent();
89: signal(SIGHUP, SIG_IGN);
90: signal(SIGINT, SIG_IGN);
91: signal(SIGQUIT, SIG_IGN);
92:
93: if (pwlock("w")) {
94: fprintf(stderr,"Password file busy -- try again");
95: goto bex;
96: }
97: #ifdef SMLROOT
98: mktemp(temp);
99: #endif
100: if((tf=fopen(temp,"w")) == NULL) {
101: printf("Cannot create temporary file\n");
102: goto bex;
103: }
104:
105: /*
106: * copy passwd to temp, replacing matching lines
107: * with new shell.
108: */
109:
110: while((pwd=getpwent()) != NULL) {
111: if(strcmp(pwd->pw_name,argv[1]) == 0) {
112: u = getuid();
113: if(u!=0 && u != pwd->pw_uid
114: #ifdef UCB_GRPMAST
115: && !(u==g && g==pwd->pw_gid)
116: #endif
117: ){
118: printf("Permission denied.\n");
119: goto out;
120: }
121: pwd->pw_shell = argv[2];
122: }
123: fprintf(tf,"%s:%s:%u:%u:%s:%s:%s\n",
124: pwd->pw_name,
125: pwd->pw_passwd,
126: pwd->pw_uid,
127: pwd->pw_gid,
128: pwd->pw_gecos,
129: pwd->pw_dir,
130: pwd->pw_shell);
131: }
132: endpwent();
133: fclose(tf);
134:
135: /*
136: * copy temp back to passwd file
137: */
138:
139: if((fi=open(temp,0)) < 0) {
140: printf("Temp file disappeared!\n");
141: goto out;
142: }
143: if((fo=creat(pwfile, 0644)) < 0) {
144: printf("Cannot recreat passwd file.\n");
145: printf("Not removing temp file.\n");
146: goto bex;
147: }
148: while((u=read(fi,buf,sizeof(buf))) > 0) write(fo,buf,u);
149:
150: out:
151: unlink(temp);
152: pwunlock();
153:
154: bex:
155: exit(1);
156: }
Defined functions
main
defined in line
32;
never used
Defined variables
buf
defined in line
30; used 3 times
defsh
defined in line
24; used 4 times
pwd
defined in line
25; used 20 times
sccsid
defined in line
1;
never used
temp
defined in line
17; used 4 times
Defined macros