]> andersk Git - moira.git/blame - clients/passwd/chsh.c
remove definition for krb_err_txt since it is defined in krb.h, and the
[moira.git] / clients / passwd / chsh.c
CommitLineData
7283d000 1/*
2 * Copyright 1988 by the Massachusetts Institute of Technology. For copying
3 * and distribution information, see the file "mit-copyright.h".
4 *
5 * $Source$
6 * $Header$
7 * $Author$
8 *
9 */
10
11#ifndef lint
12static char *rcsid_chsh_c = "$Header$";
13#endif not lint
14
15/*
8defc06b 16 * Talk to the MOIRA database to change a person's login shell. The chosen
7283d000 17 * shell must exist. A warning will be issued if the shell is not in
18 * /etc/shells.
19 *
20 * chsh with no modifiers changes the shell of the user who is running
21 * the program.
22 *
23 * If a commandline argument is given, it is taken to be the username
24 * of the user whose shell is to be changed.
25 *
26 */
27
b687d789 28#ifdef POSIX
29#include <unistd.h>
30#endif
7283d000 31#include <sys/types.h>
32#include <stdio.h>
f071d8a7 33#include <string.h>
7283d000 34#include <sys/file.h>
35#include <krb.h>
36#include <ctype.h>
37#include <errno.h>
38
8defc06b 39/* MOIRA includes */
40#include <moira.h>
41#include <moira_site.h>
7283d000 42#include "mit-copyright.h"
43
44char *whoami;
45char *getusershell();
46
7283d000 47main(argc, argv)
48 int argc;
49 char *argv[];
50{
51 char pname[ANAME_SZ];
52 char *uname = pname;
53 int k_errno;
54 char *whoami;
55
f071d8a7 56 if ((whoami = strrchr(argv[0], '/')) == NULL)
7283d000 57 whoami = argv[0];
58 else
59 whoami++;
60
61 if (argc > 2) {
62 usage();
63 }
64
65 if (argc == 2)
66 uname = argv[1];
67 else
68 {
69 /* Do it right; get name from kerberos ticket file rather than
70 from passord file. */
71
72 if (k_errno = tf_init(TKT_FILE, R_TKT_FIL)) {
73 fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
74 exit(1);
75 }
76
77 if (k_errno = tf_get_pname(pname)) {
78 fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
79 exit(1);
80 }
81
82 tf_close();
83 }
84
85 exit(chsh(uname));
86}
87
88leave(status)
89 int status;
8defc06b 90 /* This should be called rather than exit once connection to moira server
7283d000 91 has been established. */
92{
8defc06b 93 mr_disconnect();
7283d000 94 exit(status);
95}
96
97scream()
98{
95cd286e 99 com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch");
7283d000 100 leave(1);
101}
102
103chsh(uname)
104 char *uname;
105{
106 int status; /* general purpose exit status */
8defc06b 107 int q_argc; /* argc for mr_query */
108 char *q_argv[U_END]; /* argv for mr_query */
109 char *motd; /* determine MR server status */
7283d000 110
111 int got_one = 0; /* have we got a new shell yet? */
112 char shell[BUFSIZ]; /* the new shell */
113 int get_shell();
114 void check_shell(); /* make sure new shell is valid */
115
116 /* Try each query. If we ever fail, print error message and exit. */
117
8defc06b 118 status = mr_connect(NULL);
7283d000 119 if (status) {
95cd286e 120 com_err(whoami, status, " while connecting to Moira");
7283d000 121 exit(1);
122 }
123
8defc06b 124 status = mr_motd(&motd);
262ca740 125 if (status) {
126 com_err(whoami, status, " unable to check server status");
127 leave(1);
128 }
129 if (motd) {
95cd286e 130 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
262ca740 131 leave(1);
132 }
133
8defc06b 134 status = mr_auth("chsh"); /* Don't use argv[0] - too easy to fake */
7283d000 135 if (status) {
136 com_err(whoami, status,
137 " while authenticating -- run \"kinit\" and try again.");
138 leave(1);
139 }
140
141 /* First, do an access check */
142
143 q_argv[USH_NAME] = uname;
144 q_argv[USH_SHELL] = "junk";
145 q_argc = USH_END;
146
8defc06b 147 if (status = mr_access("update_user_shell", q_argc, q_argv))
7283d000 148 {
149 com_err(whoami, status, "; shell not\nchanged.");
150 leave(2);
151 }
152
153 printf("Changing login shell for %s.\n", uname);
154
155 /* Display current information */
156
157 q_argv[NAME] = uname;
158 q_argc = NAME + 1;
159
7be7e273 160 if ((status = mr_query("get_user_account_by_login", q_argc, q_argv,
7283d000 161 get_shell, (char *) uname)))
162 {
163 com_err(whoami, status, " while getting user information.");
164 leave(2);
165 }
166
167 /* Ask for new shell */
168 while (!got_one)
169 {
170 printf("New shell: ");
5bd0a4c4 171 if (fgets(shell, sizeof(shell), stdin) == NULL)
172 leave(0);
7283d000 173 got_one = (strlen(shell) > 1);
174 }
175
176 shell[strlen(shell) - 1] = 0; /* strip off newline */
177
178 /* Make sure we have a valid shell. This routine could exit */
179 check_shell(shell);
180
181 /* Change shell */
182
183 printf("Changing shell to %s...\n", shell);
184
185 q_argv[USH_NAME] = uname;
186 q_argv[USH_SHELL] = shell;
187 q_argc = USH_END;
8defc06b 188 if (status = mr_query("update_user_shell", q_argc, q_argv,
7283d000 189 scream, (char *) NULL))
190 {
191 com_err(whoami, status, " while changing shell.");
192 leave(2);
193 }
194
195 printf("Shell successfully changed.\n");
8defc06b 196 mr_disconnect();
7283d000 197
198 return(0);
199}
200
201get_shell(argc, argv, uname)
202 int argc;
203 char **argv;
204 char *uname; /* for sanity checking */
205{
206 /* We'll just take the first information we get since login names
207 cannot be duplicated in the database. */
208
b687d789 209 if (argc < U_END || strcmp(argv[U_NAME], uname))
7283d000 210 {
211 fprintf(stderr, "Some internal error has occurred. Try again.\n");
212 leave(3);
213 }
214
215 printf("Account information last changed on %s\n", argv[U_MODTIME]);
216 printf("by user %s with %s.\n", argv[U_MODBY], argv[U_MODWITH]);
217 printf("Current shell for %s is %s.\n", uname, argv[U_SHELL]);
218
8defc06b 219 return(MR_ABORT); /* Don't pay attention to other matches. */
7283d000 220}
221
222void check_shell(shell)
223 char *shell;
224{
225 char *valid_shell;
226 int ok = 0;
227
228 while (valid_shell = getusershell()) {
229 if (strcmp(shell, valid_shell) == NULL) {
230 ok = 1;
231 break;
232 }
f071d8a7 233 else if (strcmp(shell, 1+strrchr(valid_shell, '/')) == NULL) {
7283d000 234 ok = 1;
235 (void) strcpy(shell, valid_shell);
236 break;
237 }
238 }
239
240 if (!ok) {
241 if (shell[0] != '/') {
242 fprintf(stderr, "%s it not a standard shell. ", shell);
243 fprintf(stderr, "You may choose to use a nonstandard\n");
244 fprintf(stderr, "shell, but you must specify its complete ");
245 fprintf(stderr, "path name.\n");
246 leave(2);
247 }
248 else if (access(shell, X_OK)) {
249 fprintf(stderr, "%s is not available.\n", shell);
250 leave(2);
251 }
252 else {
253 printf("%s exists but is an unusual choice.\n", shell);
254 printf("Try again if it is not what you wanted.\n");
255 }
256 }
257}
258
259usage()
260{
261 fprintf(stderr, "Usage: %s [user]\n", whoami);
262 exit(1);
263}
fa00aa12 264
0ffa8026 265#if defined(ultrix) || defined(_AIX) || defined(sgi)
fa00aa12 266char *getusershell()
267{
268 static int count = 1;
269
270 switch (count++) {
271 case 1:
272 return("/bin/sh");
273 case 2:
274 return("/bin/csh");
275 case 3:
0ffa8026 276 return("/bin/athena/tcsh");
277 case 4:
fa00aa12 278 return(NULL);
279 default:
280 count = 1;
281 return(getusershell());
282 }
283}
a2ff3b56 284#endif
This page took 0.112055 seconds and 5 git commands to generate.