]> andersk Git - moira.git/blame - clients/passwd/chfn.c
remove definition for krb_err_txt since it is defined in krb.h, and the
[moira.git] / clients / passwd / chfn.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_chfn_c = "$Header$";
13#endif not lint
14
15/*
8defc06b 16 * Talk to the MOIRA database to change a person's GECOS information.
7283d000 17 *
18 * chfn with no modifiers changes the information of the user who is
19 * running the program.
20 *
21 * If a commandline argument is given, it is taken to be the username
22 * of the user whose information is to be changed.
23 *
24 */
25
26#define FALSE 0
27#define TRUE 1
28
29#include <sys/types.h>
30#include <stdio.h>
f071d8a7 31#include <string.h>
7283d000 32#include <sys/file.h>
33#include <krb.h>
34#include <ctype.h>
35#include <errno.h>
36
8defc06b 37/* MOIRA includes */
38#include <moira.h>
39#include <moira_site.h>
7283d000 40#include "mit-copyright.h"
41
42char *whoami;
43
7283d000 44struct finger_info {
45 char *fullname;
46 char *nickname;
47 char *home_address;
48 char *home_phone;
49 char *office_address;
50 char *office_phone;
51 char *mit_department;
52 char *mit_year;
53};
54
55main(argc, argv)
56 int argc;
57 char *argv[];
58{
59 char pname[ANAME_SZ];
60 char *uname = pname;
61 int k_errno;
62 char *whoami;
63
f071d8a7 64 if ((whoami = strrchr(argv[0], '/')) == NULL)
7283d000 65 whoami = argv[0];
66 else
67 whoami++;
68
69 if (argc > 2) {
70 usage();
71 }
72
73 if (argc == 2)
74 uname = argv[1];
75 else
76 {
77 /* Do it right; get name from kerberos ticket file rather than
78 from passord file. */
79
80 if (k_errno = tf_init(TKT_FILE, R_TKT_FIL)) {
81 fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
82 exit(1);
83 }
84
85 if (k_errno = tf_get_pname(pname)) {
86 fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
87 exit(1);
88 }
89
90 tf_close();
91 }
92
93 exit(chfn(uname));
94}
95
96leave(status)
97 int status;
8defc06b 98 /* This should be called rather than exit once connection to moira server
7283d000 99 has been established. */
100{
8defc06b 101 mr_disconnect();
7283d000 102 exit(status);
103}
104
105scream()
106{
95cd286e 107 com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch");
7283d000 108 leave(1);
109}
110
111chfn(uname)
112 char *uname;
113{
114 int status; /* general purpose exit status */
8defc06b 115 int q_argc; /* argc for mr_query */
116 char *q_argv[F_END]; /* argv for mr_query */
117 char *motd; /* for MR server status */
7283d000 118 int i;
119
120 int get_user_info();
121 void get_new_info();
122
123 struct finger_info old_info;
124 struct finger_info new_info;
125
126 /* Try each query. If we ever fail, print error message and exit. */
127
8defc06b 128 status = mr_connect(NULL);
7283d000 129 if (status) {
29956ef1 130 com_err(whoami, status, "while connecting to Moira");
7283d000 131 exit(1);
132 }
133
8defc06b 134 status = mr_motd(&motd);
262ca740 135 if (status) {
29956ef1 136 com_err(whoami, status, "unable to check server status");
262ca740 137 leave(1);
138 }
139 if (motd) {
95cd286e 140 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
262ca740 141 leave(1);
142 }
143
8defc06b 144 status = mr_auth("chfn"); /* Don't use argv[0] - too easy to fake */
7283d000 145 if (status) {
146 com_err(whoami, status,
29956ef1 147 "while authenticating -- run \"kinit\" and try again.");
7283d000 148 leave(1);
149 }
150
151 /* First, do an access check. */
152
153 q_argv[F_NAME] = uname;
154 for (i = F_NAME + 1; i < F_MODTIME; i++)
155 q_argv[i] = "junk";
156 q_argc = F_MODTIME; /* one more than the last updatable field */
157
8defc06b 158 if (status = mr_access("update_finger_by_login", q_argc, q_argv)) {
7283d000 159 com_err(whoami, status, "; finger\ninformation not changed.");
160 leave(2);
161 }
162
163 printf("Changing finger information for %s.\n", uname);
164
165 /* Get information */
166
167 q_argv[NAME] = uname;
168 q_argc = NAME + 1;
8defc06b 169 if (status = mr_query("get_finger_by_login", q_argc, q_argv,
7283d000 170 get_user_info, (char *) &old_info))
171 {
29956ef1 172 com_err(whoami, status, "while getting user information.");
7283d000 173 leave(2);
174 }
175
176 /* Get the new information from the user */
177
178 get_new_info(&old_info, &new_info);
179
180 /* Do the update */
181
182 printf("Changing finger information...\n");
183
184 q_argv[F_NAME] = uname;
185 q_argv[F_FULLNAME] = new_info.fullname;
186 q_argv[F_NICKNAME] = new_info.nickname;
187 q_argv[F_HOME_ADDR] = new_info.home_address;
188 q_argv[F_HOME_PHONE] = new_info.home_phone;
189 q_argv[F_OFFICE_ADDR] = new_info.office_address;
190 q_argv[F_OFFICE_PHONE] = new_info.office_phone;
191 q_argv[F_MIT_DEPT] = new_info.mit_department;
192 q_argv[F_MIT_AFFIL] = new_info.mit_year;
193 q_argc = F_MODTIME; /* First non-update query argument */
194
8defc06b 195 if (status = mr_query("update_finger_by_login", q_argc, q_argv,
7283d000 196 scream, (char *)NULL))
197 {
29956ef1 198 com_err(whoami, status, "while updating finger information.");
7283d000 199 leave(1);
200 }
201
202 printf("Finger information updated succesfully.\n");
203
204 return(0);
205}
206
207get_user_info(argc, argv, message)
208 int argc;
209 char *argv[];
210 char *message;
211{
212 struct finger_info *old_info = (struct finger_info *) message;
213
214 if (argc != F_END) {
215 fprintf(stderr, "Some internal error occurred; try again.\n");
216 leave(3);
217 }
218
219 printf("Info last changed on %s by user %s with %s.\n",
220 argv[F_MODTIME], argv[F_MODBY], argv[F_MODWITH]);
221
222 old_info->fullname = strsave(argv[F_FULLNAME]);
223 old_info->nickname = strsave(argv[F_NICKNAME]);
224 old_info->home_address = strsave(argv[F_HOME_ADDR]);
225 old_info->home_phone = strsave(argv[F_HOME_PHONE]);
226 old_info->office_address = strsave(argv[F_OFFICE_ADDR]);
227 old_info->office_phone = strsave(argv[F_OFFICE_PHONE]);
228 old_info->mit_department = strsave(argv[F_MIT_DEPT]);
229 old_info->mit_year = strsave(argv[F_MIT_AFFIL]);
230
231 /* Only pay attention to the first match since login names are
232 unique in the database. */
8defc06b 233 return(MR_ABORT);
7283d000 234}
235
236char *ask(question, def_val, phone_num)
237 char *question;
238 char *def_val;
239 int phone_num; /* True if this must contain only digits */
240{
12487417 241 static char buf[BUFSIZ];
7283d000 242 int ok = FALSE;
243 char *result;
244 int i;
245 int dashes = FALSE;
246
247#define BLANK "none"
248
249 while (!ok)
250 {
251 ok = TRUE;
252 printf("%s [%s]: ", question, def_val);
12487417 253 if (fgets(buf, sizeof(buf), stdin) == NULL)
254 leave(0);
7283d000 255 buf[strlen(buf) - 1] = NULL;
256 if (strlen(buf) == 0)
257 result = def_val;
258 else if (strcasecmp(buf, BLANK) == NULL)
259 result = "";
260 else
261 result = buf;
262
263 for (i = 0; i < strlen(buf); i++)
264 {
265 switch (buf[i])
266 {
267 case '"':
268 printf("'\"' is not allowed.\n");
269 ok = FALSE;
270 break;
271 case ',':
272 printf("',' is not allowed.\n");
273 ok = FALSE;
274 break;
275 case ':':
276 printf("':' is not allowed.\n");
277 ok = FALSE;
278 break;
279 default:
280 if (iscntrl(buf[i])) {
281 printf("Control characters are not allowed.\n");
282 ok = FALSE;
283 break;
284 }
285 }
286 if (!ok)
287 break;
288 }
289
290 if (phone_num && ok) {
1603d7ed 291 for (i = 0; i < strlen(result); i++) {
292 if (!isdigit(result[i]) && (result[i] != '-')) {
7283d000 293 printf("Phone numbers can contain only digits.\n");
294 ok = FALSE;
295 break;
296 }
1603d7ed 297 if (result[i] == '-')
7283d000 298 dashes = TRUE;
299 }
300 }
301 }
302
303 /* Remove dashes if necessary */
12487417 304 if (dashes && result == buf) {
7283d000 305 char *tmp1, *tmp2;
12487417 306 tmp1 = tmp2 = (char *)buf;
7283d000 307 do {
308 if (*(tmp1) != '-')
309 *(tmp2++) = *(tmp1);
310 }
311 while (*(tmp1++));
312 }
313
314 return(result);
315}
316
317void get_new_info(old_info, new_info)
318 struct finger_info *old_info;
319 struct finger_info *new_info;
320{
321 printf("Default values are printed inside of '[]'.\n");
322 printf("To accept the default, type <return>.\n");
323 printf("To have a blank entry, type the word '%s'.\n\n", BLANK);
324
325#define GETINFO(m,v,n) \
326 new_info->v = strsave(ask(m, old_info->v, n))
327
328 GETINFO("Full name", fullname, FALSE);
329 GETINFO("Nickname", nickname, FALSE);
330 GETINFO("Home address (Ex: Atkinson 304)", home_address, FALSE);
331 GETINFO("Home phone number (Ex: 3141592)", home_phone, TRUE);
332 GETINFO("Office address (Exs: E40-342 or 2-108)",
333 office_address, FALSE);
334 GETINFO("Office phone (Ex: 3-1300)", office_phone, TRUE);
29956ef1 335 GETINFO("MIT department (Exs: 9, Biology, Information Services)",
7283d000 336 mit_department, FALSE);
337 GETINFO("MIT year (Exs: 1989, '91, Faculty, Grad)", mit_year, FALSE);
338}
339
340usage()
341{
342 fprintf(stderr, "Usage: %s [user]\n", whoami);
343 exit(1);
344}
This page took 0.132819 seconds and 5 git commands to generate.