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