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