]> andersk Git - moira.git/blame - reg_svr/reg_svr.c
handle errors in REPLICAT services correctly; remove non-functional if
[moira.git] / reg_svr / reg_svr.c
CommitLineData
47baf534 1/*
3e9b5b7b 2 * $Source$
3 * $Author$
4 * $Header$
47baf534 5 *
3e9b5b7b 6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
47baf534 7 *
3e9b5b7b 8 * Server for user registration with SMS and Kerberos.
47baf534 9 *
803d15cb 10 * This program is a client of the Kerberos admin_server and a
11 * server for the userreg program. It is not a client of the
12 * SMS server as it is linked with libsmsglue which bypasses
13 * the network protocol.
47baf534 14 */
15
16#ifndef lint
17static char *rcsid_reg_svr_c = "$Header$";
18#endif lint
19
a640951a 20#include "reg_svr.h"
f46fccfa 21#include "admin_server.h"
007fdd80 22#include "admin_err.h"
47baf534 23
f46fccfa 24extern int krb_err_base;
25extern char admin_errmsg[];
47baf534 26
f3c010f8 27static char krbhst[BUFSIZ]; /* kerberos server name */
28static char krbrealm[REALM_SZ]; /* kerberos realm name */
29
bac67528 30main(argc,argv)
31 int argc;
32 char *argv[];
47baf534 33{
3e9b5b7b 34 struct msg message; /* Storage for parsed packet */
29bc4461 35 int status = SUCCESS; /* Error status */
bac67528 36 char retval[BUFSIZ]; /* Buffer to hold return message for client */
37
a640951a 38 void req_initialize(); /* Initialize request layer */
39 void get_request(); /* Get a request */
40 void report(); /* Respond to a request */
bac67528 41
a640951a 42 /* Initialize */
bac67528 43 whoami = argv[0];
a640951a 44
45 /* Use com_err or output to stderr for all log messages. */
46#ifdef DEBUG
47 fprintf(stderr,"*** Debugging messages enabled. ***\n");
48#endif DEBUG
49
3e9b5b7b 50 /* Error messages sent one line at a time */
f46fccfa 51 setlinebuf(stderr);
47baf534 52
29bc4461 53 /* Initialize user registration error table for com_err */
47baf534 54 init_ureg_err_tbl();
3e9b5b7b 55
3e9b5b7b 56 /* Connect to the SMS server */
57 if ((status = sms_connect()) != SMS_SUCCESS)
58 {
bac67528 59 com_err(whoami, status, " on connect");
78eff417 60 exit(1);
61 }
3e9b5b7b 62
63 /* Authorize, telling the server who you are */
bac67528 64 if ((status = sms_auth(whoami)) != SMS_SUCCESS)
3e9b5b7b 65 {
bac67528 66 com_err(whoami, status, " on auth");
78eff417 67 exit(1);
68 }
a640951a 69
f3c010f8 70 if (status = get_krbrlm(krbrealm, 1)) {
71 status += krb_err_base;
72 com_err(whoami, status, " fetching kerberos realm");
73 exit(1);
74 }
a640951a 75
f3c010f8 76 if (status = get_krbhst(krbhst, krbrealm, 1)) {
77 status += krb_err_base;
78 com_err(whoami, status, " fetching kerberos hostname");
79 exit(1);
80 } else {
81 char *s;
82 for (s = krbhst; *s && *s != '.'; s++)
83 if (isupper(*s))
84 *s = tolower(*s);
85 *s = 0;
86 }
0349fd4d 87
88 journal = fopen(JOURNAL, "a");
89 if (journal == NULL) {
90 com_err(whoami, errno, " while opening journal file");
91 exit(1);
92 }
a640951a 93
94 /* Allow request layer to initialize */
95 req_initialize();
96
3e9b5b7b 97 /* Sit around waiting for requests from the client. */
98 for (;;)
99 {
a640951a 100 get_request(&message);
3e9b5b7b 101
3e9b5b7b 102 switch((int)message.request)
103 {
104 case UREG_VERIFY_USER:
bac67528 105 status = verify_user(&message,retval);
47baf534 106 break;
3e9b5b7b 107 case UREG_RESERVE_LOGIN:
bac67528 108 status = reserve_user(&message,retval);
47baf534 109 break;
3e9b5b7b 110 case UREG_SET_PASSWORD:
bac67528 111 status = set_password(&message,retval);
47baf534 112 break;
113
3e9b5b7b 114 default:
47baf534 115 status = UREG_UNKNOWN_REQUEST;
a640951a 116 critical_alert(FAIL_INST,"Unknown request %d from userreg.",
117 message.request);
47baf534 118 break;
119 }
47baf534 120
3e9b5b7b 121 /* Report what happened to client */
a640951a 122 report(status, retval);
47baf534 123 }
124}
125
eb39a9ea 126/* This is necessary so that this server can know where to put its
127 tickets. */
128char *tkt_string()
129{
130 return("/tmp/tkt_ureg");
131}
132
bac67528 133int parse_encrypted(message,data)
3e9b5b7b 134 struct msg *message; /* Formatted packet */
bac67528 135 struct db_data *data; /* Data from the SMS database */
3e9b5b7b 136/* This routine makes sure that the ID from the database matches
137 the ID sent accross in the packet. The information in the packet
138 was created in the following way:
139
803d15cb 140 The plain text ID number was encrypted via EncryptID() resulting
141 in the form that would appear in the SMS database. This is
29bc4461 142 concatinated to the plain text ID so that the ID string contains plain
143 text ID followed by a null followed by the encrypted ID. Other
144 information such as the username or password is appended. The whole
145 thing is then DES encrypted using the encrypted ID as the source of
146 the key.
3e9b5b7b 147
148 This routine tries each encrypted ID in the database that belongs
149 to someone with this user's first and last name and tries to
bac67528 150 decrypt the packet with this information. If it succeeds, it returns
29bc4461 151 zero and initializes all the fields of the formatted packet structure
152 that depend on the encrypted information. */
47baf534 153{
3e9b5b7b 154 C_Block key; /* The key for DES en/decryption */
155 Key_schedule sched; /* En/decryption schedule */
156 static char decrypt[BUFSIZ]; /* Buffer to hold decrypted information */
157 long decrypt_len; /* Length of decypted ID information */
158 char recrypt[14]; /* Buffer to hold re-encrypted information */
159 static char hashid[14]; /* Buffer to hold one-way encrypted ID */
160 char idnumber[BUFSIZ]; /* Buffer to hold plain-text ID */
bac67528 161 char *temp; /* A temporary string pointer */
162 int len; /* Keeps track of length left in packet */
29bc4461 163 int status = SUCCESS; /* Error status */
3e9b5b7b 164
bac67528 165#ifdef DEBUG
166 com_err(whoami,0,"Entering parse_encrypted");
167#endif
168
3e9b5b7b 169 /* Make the decrypted information length the same as the encrypted
170 information length. Both are integral multples of eight bytes
171 because of the DES encryption routines. */
bac67528 172 decrypt_len = (long)message->encrypted_len;
47baf534 173
3e9b5b7b 174 /* Get key from the one-way encrypted ID in the SMS database */
bac67528 175 string_to_key(data->mit_id, key);
3e9b5b7b 176 /* Get schedule from key */
47baf534 177 key_sched(key, sched);
3e9b5b7b 178 /* Decrypt information from packet using this key. Since decrypt_len
179 is an integral multiple of eight bytes, it will probably be null-
180 padded. */
bac67528 181 pcbc_encrypt(message->encrypted,decrypt, decrypt_len, sched, key, DECRYPT);
3e9b5b7b 182
183 /* Extract the plain text and encrypted ID fields from the decrypted
184 packet information. */
185 /* Since the decrypted information starts with the plain-text ID
186 followed by a null, if the decryption worked, this will only
187 copy the plain text part of the decrypted information. It is
188 important that strncpy be used because if we are not using the
189 correct key, there is no guarantee that a null will occur
190 anywhere in the string. */
29bc4461 191 (void) strncpy(idnumber,decrypt,(int)decrypt_len);
3e9b5b7b 192 /* Point temp to the end of the plain text ID number. */
47baf534 193 temp = decrypt + strlen(idnumber) + 1;
29bc4461 194 /* Find out how much more packet there is. */
bac67528 195 len = message->encrypted_len - (temp - decrypt);
29bc4461 196 /* Copy the next CRYPT_LEN bytes of the decrypted information into
197 hashid if there are CRYPT_LEN more bytes to copy. There will be
3e9b5b7b 198 if we have the right key. */
29bc4461 199 (void) strncpy(hashid, temp, min(len, CRYPT_LEN));
3e9b5b7b 200 /* Point temp to the end of the encrypted ID field */
47baf534 201 temp += strlen(hashid) + 1;
3e9b5b7b 202 /* Find out how much more room there is. */
bac67528 203 len = message->encrypted_len - (temp - decrypt);
3e9b5b7b 204
bac67528 205 /* Now compare encrypted ID's don't match. */
803d15cb 206 if (strcmp(hashid, data->mit_id)) status = FAILURE;
29bc4461 207 if (status == SUCCESS)
3e9b5b7b 208 {
803d15cb 209 EncryptID(recrypt, idnumber, message->first, message->last);
bac67528 210 /* Now compare encrypted plain text to ID from database. */
803d15cb 211 if (strcmp(recrypt, data->mit_id)) status = FAILURE;
47baf534 212 }
3e9b5b7b 213
29bc4461 214 if (status == SUCCESS)
bac67528 215 {
216 /* We made it. Now we can finish initializing message. */
217 /* Point leftover to whatever is left over! */
218 message->leftover = temp;
219 message->leftover_len = len;
220 /* Since we know we have the right user, fill in the information
221 from the SMS database. */
222 message->db.reg_status = data->reg_status;
29bc4461 223 (void) strncpy(message->db.uid,data->uid, sizeof(message->db.uid));
224 (void) strncpy(message->db.mit_id,data->mit_id,
225 sizeof(message->db.mit_id));
226 (void) strncpy(message->db.login,data->login, sizeof(message->db.login));
bac67528 227 }
47baf534 228
bac67528 229#ifdef DEBUG
230 if (status)
29bc4461 231 com_err(whoami,status," parse_encrypted failed.");
bac67528 232 else
29bc4461 233 com_err(whoami,status,"parse_encrypted succeeded.");
bac67528 234#endif
47baf534 235
47baf534 236 return status;
237}
238
bac67528 239int db_callproc(argc,argv,queue)
240 int argc; /* Number of arguments returned by SMS */
241 char *argv[]; /* Arguments returned by SMS */
242 struct save_queue *queue; /* Queue to save information in */
243/* This function is called by sms_query after each tuple found. It is
29bc4461 244 used by find_user to cache information about each user found. */
47baf534 245{
bac67528 246 struct db_data *data; /* Structure to store the information in */
29bc4461 247 int status = SUCCESS; /* Error status */
47baf534 248
bac67528 249#ifdef DEBUG
250 com_err(whoami,0,"Entering db_callproc.");
251#endif
252
29bc4461 253 if (argc != U_END)
3e9b5b7b 254 {
a640951a 255 critical_alert
256 (FAIL_INST,
257 "Wrong number of arguments returned from get_user_by_name.");
803d15cb 258 status = SMS_ABORT;
f46fccfa 259 }
bac67528 260 else
3e9b5b7b 261 {
bac67528 262 /* extract the needed information from the results of the SMS query */
263 data = (struct db_data *)malloc(sizeof(struct db_data));
29bc4461 264 data->reg_status = atoi(argv[U_STATE]);
265 (void) strncpy(data->login,argv[U_NAME],sizeof(data->login));
266 (void) strncpy(data->mit_id,argv[U_MITID],sizeof(data->mit_id));
267 (void) strncpy(data->uid,argv[U_UID],sizeof(data->uid));
bac67528 268#ifdef DEBUG
269 fprintf(stderr,"Found in database:\n");
270 fprintf(stderr," Registration status: %d\n",data->reg_status);
271 fprintf(stderr," login: %s\n",data->login);
272 fprintf(stderr," MIT ID: %s\n",data->mit_id);
273 fprintf(stderr," uid: %s\n",data->uid);
274#endif
275 sq_save_data(queue,data);
47baf534 276 }
bac67528 277
278 return status;
279}
3e9b5b7b 280
bac67528 281int find_user(message)
282 struct msg *message; /* Formatted packet structure */
283/* This routine verifies that a user is allowed to register by finding
284 him/her in the SMS database. It returns the status of the SMS
285 query that it calls. */
286{
803d15cb 287#define GUBN_ARGS 2 /* Arguements needed by get_user_by_name */
bac67528 288 char *q_name; /* Name of query */
29bc4461 289 int q_argc; /* Number of arguments for query */
290 char *q_argv[GUBN_ARGS]; /* Arguments to query */
291 int status = SUCCESS; /* Query return status */
bac67528 292
293 struct save_queue *queue; /* Queue to hold SMS data */
294 struct db_data *data; /* Structure for data for one tuple */
29bc4461 295 short verified = FALSE; /* Have we verified the user? */
bac67528 296
297 /* Zero the mit_id field in the formatted packet structure. This
298 being zeroed means that no user was found. */
299 bzero(message->db.mit_id,sizeof(message->db.mit_id));
300
29bc4461 301 if (status == SUCCESS)
3e9b5b7b 302 {
bac67528 303 /* Get ready to make an SMS query */
304 q_name = "get_user_by_name";
29bc4461 305 q_argc = GUBN_ARGS; /* #defined in this routine */
bac67528 306 q_argv[0] = message->first;
307 q_argv[1] = message->last;
308
309 /* Create queue to hold information */
310 queue = sq_create();
311
312 /* Do it */
313 status = sms_query(q_name,q_argc,q_argv,db_callproc,(char *)queue);
314
315#ifdef DEBUG
803d15cb 316 fprintf(stderr," %d returned by get_user_by_name\n",status);
bac67528 317#endif
318
319 if (status == SMS_SUCCESS)
320 {
321 /* Traverse the list, freeing data as we go. If sq_get_data()
322 returns zero if there is no more data on the queue. */
323 while (sq_get_data(queue,&data))
324 {
325 if (!verified)
326 /* parse_encrypted returns zero on success */
29bc4461 327 verified = (parse_encrypted(message,data) == SUCCESS);
328 free((char *)data);
bac67528 329 }
330 }
29bc4461 331
332 /* Destroy the queue */
333 sq_destroy(queue);
47baf534 334 }
47baf534 335
bac67528 336#ifdef DEBUG
337 fprintf(stderr,"Returned from find_user\n");
338 fprintf(stderr," MIT ID: %s\n", message->db.mit_id);
339 fprintf(stderr," Registration status: %d\n",message->db.reg_status);
340 fprintf(stderr," uid: %s\n",message->db.uid);
341 fprintf(stderr," login: %s\n",message->db.login);
342 fprintf(stderr," Status from query: %d\n",status);
343#endif DEBGUG
344
345 return status;
346}
347
bac67528 348int verify_user(message,retval)
3e9b5b7b 349 struct msg *message;
bac67528 350 char *retval;
29bc4461 351 /* This routine determines whether a user is in the databse and returns
352 his state so that other routines can figure out whether he is the
353 correct state for various transactions. */
354
47baf534 355{
29bc4461 356 int status = SUCCESS; /* Return status */
bac67528 357
358 /* Log that we are about to veryify user */
359 com_err(whoami,0,"verify_user %s %s",message->first,message->last);
360
361 /* Figure out what user (if any) can be found based on the
362 encrypted information in the packet. (See the comment on
363 parse_encrypted().) */
bac67528 364
365 status = find_user(message);
366
367 /* If SMS coudn't find the user */
368 if (status == SMS_NO_MATCH)
f46fccfa 369 status = UREG_USER_NOT_FOUND;
bac67528 370 else if (status == SMS_SUCCESS)
3e9b5b7b 371 {
bac67528 372 /* If the information sent over in the packet did not point to a
373 valid user, the mit_id field in the formatted packet structure
374 will be empty. */
29bc4461 375 if (message->db.mit_id[0] == NULL)
bac67528 376 status = UREG_USER_NOT_FOUND;
377 /* If the user was found but the registration has already started,
378 use this as the status */
379 else
380 {
381 switch (message->db.reg_status)
382 {
29bc4461 383 case US_NO_LOGIN_YET:
bac67528 384 status = SUCCESS;
385 break;
29bc4461 386 case US_REGISTERED:
bac67528 387 status = UREG_ALREADY_REGISTERED;
388 break;
29bc4461 389 case US_NO_PASSWD:
bac67528 390 status = UREG_NO_PASSWD_YET;
391 break;
29bc4461 392 case US_DELETED:
bac67528 393 status = UREG_DELETED;
394 break;
29bc4461 395 case US_NOT_ALLOWED:
bac67528 396 status = UREG_NOT_ALLOWED;
397 break;
29bc4461 398
bac67528 399 default:
400 status = UREG_MISC_ERROR;
a640951a 401 critical_alert(FAIL_INST,"Bad user state for login %s.",
402 message->db.login);
bac67528 403 break;
404 }
405 /* Set retval to the login name so that the client can use
406 it in the error message it will give the user. */
29bc4461 407 (void) strcpy(retval,message->db.login);
bac67528 408 }
47baf534 409 }
3e9b5b7b 410
29bc4461 411 com_err(whoami,status," returned from verify_user");
bac67528 412
47baf534 413 return status;
414}
bac67528 415
416int ureg_get_tkt()
47baf534 417{
29bc4461 418 int status = SUCCESS; /* Return status */
bac67528 419
420 /* Get keys for interacting with Kerberos admin server. */
f3c010f8 421 /* principal, instance, realm, service, service instance, life, file */
422 if (status = get_svc_in_tkt("register", "sms", krbrealm, "changepw",
423 krbhst, 1, KEYFILE))
bac67528 424 status += krb_err_base;
425
803d15cb 426#ifdef DEBUG
427 if (status == SUCCESS)
428 com_err(whoami,status,"Succeeded in getting tickets.");
429 else
430 com_err(whoami,status,"Failed to get tickets.");
431#endif
bac67528 432 return status;
47baf534 433}
434
bac67528 435int null_callproc(argc,argv,message)
436 int argc;
437 char *argv[];
3e9b5b7b 438 char *message;
bac67528 439 /* This routine is a null callback that should be used for queries that
440 do not return tuples. If it ever gets called, something is wrong. */
47baf534 441{
a640951a 442 critical_alert(FAIL_INST,"Something returned from an update query.");
803d15cb 443 return FAILURE;
47baf534 444}
445
bac67528 446int do_admin_call(login, passwd, uid)
29bc4461 447 char *login; /* Requested kerberos principal */
448 char *passwd; /* Requested password */
449 char *uid; /* Uid of user who owns this principal */
450 /* This routine gets tickets, makes the appropriate call to admin_call,
451 and destroys tickets. */
47baf534 452{
bac67528 453 int status; /* Error status */
454 char uid_buf[20]; /* Holds uid for kerberos */
455
803d15cb 456 com_err(whoami,0,"Entering do_admin_call");
457
bac67528 458 if ((status = ureg_get_tkt()) == SUCCESS)
3e9b5b7b 459 {
bac67528 460 /* Try to reserve kerberos principal. To do this, send a
461 password request and a null password. It will only succeed
462 if there is no principal or the principal exists and has no
463 password. */
803d15cb 464 /* 13 chars of placebo for backwards-compatability - the admin
465 server protocol reqires this. */
bac67528 466 bzero(uid_buf,sizeof(uid_buf));
f3c010f8 467 (void) sprintf(uid_buf, "%13s", uid);
bac67528 468
469 if ((status = admin_call(ADMIN_ADD_NEW_KEY_ATTR, login,
470 "", passwd, uid_buf)) != KSUCCESS)
3e9b5b7b 471 {
29bc4461 472 com_err(whoami,status," server error: %s",admin_errmsg);
bac67528 473
474 if (strcmp(admin_errmsg,
475 "Principal already in kerberos database.") == 0)
476 status = UREG_KRB_TAKEN;
a640951a 477 critical_alert(FAIL_INST,"%s is known to Kerberos but not SMS.",
478 login);
47baf534 479 }
47baf534 480 }
bac67528 481
482 dest_tkt();
803d15cb 483 com_err(whoami,status," returned from do_adin_call");
bac67528 484 return status;
47baf534 485}
3e9b5b7b 486
bac67528 487int reserve_user(message,retval)
488 struct msg *message;
489 char *retval;
47baf534 490{
bac67528 491 int q_argc; /* Number of arguments to query */
492 char *q_argv[3]; /* Arguments to SMS query */
493 char *q_name; /* Name of SMS query */
29bc4461 494 int status = SUCCESS; /* General purpose error status */
bac67528 495 char fstype_buf[7]; /* Buffer to hold fs_type, a 16 bit number */
496 char *login; /* The login name the user wants */
497 register int i; /* A counter */
bac67528 498
803d15cb 499 /* Log that we are about to reserve a user. */
29bc4461 500 com_err(whoami, 0, "reserve_user %s %s",
bac67528 501 message->first, message->last);
3e9b5b7b 502
bac67528 503 /* Check to make sure that we can verify this user. */
504 if ((status = verify_user(message,retval)) == SUCCESS)
3e9b5b7b 505 {
29bc4461 506 /* Get the requested login name from leftover packet information. */
bac67528 507 login = message->leftover;
29bc4461 508
509 /* Check the login name for validity. The login name is currently
510 is allowed to contain lowercase letters and numbers in any
511 position and underscore characters and periods in any position
512 but the first. */
513 if ((strlen(login) < MIN_UNAME) || (strlen(login) > MAX_UNAME))
bac67528 514 status = UREG_INVALID_UNAME;
47baf534 515 }
29bc4461 516 if (status == SUCCESS)
5fff8167 517 if (login[1] == '_')
29bc4461 518 status = UREG_INVALID_UNAME;
519 if (status == SUCCESS)
3e9b5b7b 520 {
803d15cb 521 for (i = 0; i < strlen(login); i++)
5fff8167 522 if (!islower(login[i]) && !isdigit(login[i]) &&
523 (login[i] != '_'))
803d15cb 524 {
525 status = UREG_INVALID_UNAME;
526 break;
527 }
47baf534 528 }
29bc4461 529 if (status == SUCCESS)
3e9b5b7b 530 {
bac67528 531 /* Now that we have a valid user with a valid login... */
532
533 /* First, try to reserve the user in SMS. */
29bc4461 534 (void) sprintf(fstype_buf,"%d",SMS_FS_STUDENT);
bac67528 535 q_name = "register_user";
536 q_argv[0] = message->db.uid;
537 q_argv[1] = login;
538 q_argv[2] = fstype_buf;
539 q_argc = 3;
29bc4461 540 status = sms_query(q_name,q_argc,q_argv,null_callproc,(char *)0);
bac67528 541 switch (status)
542 {
543 case SMS_SUCCESS:
544 status = SUCCESS;
545 break;
546 case SMS_IN_USE:
547 status = UREG_LOGIN_USED;
548 break;
549 default:
550 status = UREG_MISC_ERROR;
a640951a 551 critical_alert(FAIL_INST,"%s returned from register_user.",
552 error_message(status));
bac67528 553 break;
554 }
47baf534 555 }
29bc4461 556 if (status == SUCCESS)
3e9b5b7b 557 {
bac67528 558 /* SMS login was successfully created; try to reserve kerberos
559 principal. */
29bc4461 560 /* If this routine fails, store the login in the retval so
bac67528 561 that it can be used in the client-side error message. */
562 if ((status = do_admin_call(login, "", message->db.uid)) != SUCCESS)
29bc4461 563 (void) strcpy(retval, login);
47baf534 564 }
bac67528 565
29bc4461 566 com_err(whoami, status, " returned from reserve_user");
bac67528 567
47baf534 568 return status;
bac67528 569}
47baf534 570
bac67528 571int set_final_status(login)
572 char *login;
803d15cb 573 /* This routine updates a user's registration status to fully
29bc4461 574 registered. */
47baf534 575{
bac67528 576 char *q_name; /* Name of SMS query */
577 int q_argc; /* Number of arguments for SMS query */
578 char *q_argv[2]; /* Arguments to get user by uid */
29bc4461 579 char state[7]; /* Can hold a 16 bit integer */
bac67528 580 int status; /* Error status */
581
582 com_err(whoami, 0, "Setting final status for %s", login);
583
29bc4461 584 (void) sprintf(state,"%d",US_REGISTERED);
bac67528 585 q_name = "update_user_status";
586 q_argc = 2;
587 q_argv[0] = login;
29bc4461 588 q_argv[1] = state;
bac67528 589 if ((status = sms_query(q_name, q_argc, q_argv, null_callproc,
590 (char *)0)) != SMS_SUCCESS)
a640951a 591 critical_alert(FAIL_INST,"%s returned from update_user_status.",
592 error_message(status));
3e9b5b7b 593
29bc4461 594 com_err(whoami,status," returned from set_final_status");
f46fccfa 595 return status;
bac67528 596}
f46fccfa 597
bac67528 598
599int set_password(message,retval)
600 struct msg *message;
601 char *retval;
602 /* This routine is used to set the initial password for the new user. */
47baf534 603{
29bc4461 604 int status = SUCCESS; /* Return status */
bac67528 605 char *passwd; /* User's password */
bac67528 606
29bc4461 607 com_err(whoami, 0, " set_password %s %s",
bac67528 608 message->first, message->last);
609
610 status = verify_user(message,retval);
611
612 /* Don't set the password unless the registration status of the user
613 is that he exists and has no password. */
614 if (status == SUCCESS)
615 status = UREG_NO_LOGIN_YET;
616 if (status == UREG_NO_PASSWD_YET)
3e9b5b7b 617 {
bac67528 618 /* User is in proper state for this transaction. */
619
620 passwd = message->leftover;
621
622 /* Set password. */
623 if ((status = do_admin_call(message->db.login,
624 passwd, message->db.uid)) != SUCCESS)
625 /* If failure, allow login name to be used in client
626 error message */
29bc4461 627 (void) strcpy(retval,message->db.login);
bac67528 628 else
629 /* Otherwise, mark user as finished. */
630 status = set_final_status(message->db.login);
631 }
29bc4461 632 com_err(whoami, status, " returned from set_passwd");
47baf534 633
bac67528 634 return status;
635}
47baf534 636
47baf534 637/*
638 * Local Variables:
639 * mode: c
3e9b5b7b 640 * c-argdecl-indent: 2
47baf534 641 * c-brace-offset: -4
bac67528 642 * c-continued-statement-offset: 4
3e9b5b7b 643 * c-indent-level: 4
644 * c-label-offset: -2
47baf534 645 * End:
646 */
This page took 1.416768 seconds and 5 git commands to generate.