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