2 * Copyright 1988 by the Massachusetts Institute of Technology. For copying
3 * and distribution information, see the file "mit-copyright.h".
12 static char *rcsid_chsh_c = "$Header$";
16 * Talk to the MOIRA database to change a person's login shell. The chosen
17 * shell must exist. A warning will be issued if the shell is not in
20 * chsh with no modifiers changes the shell of the user who is running
23 * If a commandline argument is given, it is taken to be the username
24 * of the user whose shell is to be changed.
31 #include <sys/types.h>
41 #include <moira_site.h>
42 #include "mit-copyright.h"
55 initialize_krb_error_table();
57 if ((whoami = strrchr(argv[0], '/')) == NULL)
70 /* Do it right; get name from kerberos ticket file rather than
73 if (k_errno = tf_init(TKT_FILE, R_TKT_FIL)) {
74 com_err(whoami, k_errno, "reading ticket file");
78 if (k_errno = tf_get_pname(pname)) {
79 com_err(whoami, k_errno, "getting kerberos principal name");
91 /* This should be called rather than exit once connection to moira server
92 has been established. */
100 com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch");
107 int status; /* general purpose exit status */
108 int q_argc; /* argc for mr_query */
109 char *q_argv[U_END]; /* argv for mr_query */
110 char *motd; /* determine MR server status */
112 int got_one = 0; /* have we got a new shell yet? */
113 char shell[BUFSIZ]; /* the new shell */
115 void check_shell(); /* make sure new shell is valid */
117 /* Try each query. If we ever fail, print error message and exit. */
119 status = mr_connect(NULL);
121 com_err(whoami, status, " while connecting to Moira");
125 status = mr_motd(&motd);
127 com_err(whoami, status, " unable to check server status");
131 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
135 status = mr_auth("chsh"); /* Don't use argv[0] - too easy to fake */
137 com_err(whoami, status,
138 " while authenticating -- run \"kinit\" and try again.");
142 /* First, do an access check */
144 q_argv[USH_NAME] = uname;
145 q_argv[USH_SHELL] = "junk";
148 if (status = mr_access("update_user_shell", q_argc, q_argv))
150 com_err(whoami, status, "; shell not\nchanged.");
154 printf("Changing login shell for %s.\n", uname);
156 /* Display current information */
158 q_argv[NAME] = uname;
161 if ((status = mr_query("get_user_account_by_login", q_argc, q_argv,
162 get_shell, (char *) uname)))
164 com_err(whoami, status, " while getting user information.");
168 /* Ask for new shell */
171 printf("New shell: ");
172 if (fgets(shell, sizeof(shell), stdin) == NULL)
174 got_one = (strlen(shell) > 1);
177 shell[strlen(shell) - 1] = 0; /* strip off newline */
179 /* Make sure we have a valid shell. This routine could exit */
184 printf("Changing shell to %s...\n", shell);
186 q_argv[USH_NAME] = uname;
187 q_argv[USH_SHELL] = shell;
189 if (status = mr_query("update_user_shell", q_argc, q_argv,
190 scream, (char *) NULL))
192 com_err(whoami, status, " while changing shell.");
196 printf("Shell successfully changed.\n");
202 get_shell(argc, argv, uname)
205 char *uname; /* for sanity checking */
207 /* We'll just take the first information we get since login names
208 cannot be duplicated in the database. */
210 if (argc < U_END || strcmp(argv[U_NAME], uname))
212 fprintf(stderr, "Some internal error has occurred. Try again.\n");
216 printf("Account information last changed on %s\n", argv[U_MODTIME]);
217 printf("by user %s with %s.\n", argv[U_MODBY], argv[U_MODWITH]);
218 printf("Current shell for %s is %s.\n", uname, argv[U_SHELL]);
220 return(MR_ABORT); /* Don't pay attention to other matches. */
223 void check_shell(shell)
229 while (valid_shell = getusershell()) {
230 if (strcmp(shell, valid_shell) == 0) {
234 else if (strcmp(shell, 1+strrchr(valid_shell, '/')) == 0) {
236 (void) strcpy(shell, valid_shell);
242 if (shell[0] != '/') {
243 fprintf(stderr, "%s it not a standard shell. ", shell);
244 fprintf(stderr, "You may choose to use a nonstandard\n");
245 fprintf(stderr, "shell, but you must specify its complete ");
246 fprintf(stderr, "path name.\n");
249 else if (access(shell, X_OK)) {
250 fprintf(stderr, "%s is not available.\n", shell);
254 printf("%s exists but is an unusual choice.\n", shell);
255 printf("Try again if it is not what you wanted.\n");
262 fprintf(stderr, "Usage: %s [user]\n", whoami);
266 #if defined(ultrix) || defined(_AIX) || defined(sgi)
269 static int count = 1;
277 return("/bin/athena/tcsh");
282 return(getusershell());