2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* AFS SIA mechanism library.
14 #include <afsconfig.h>
15 #include <afs/param.h>
20 #include <sys/types.h>
26 #include <afs/com_err.h>
28 #include <afs/cellconfig.h>
30 #include <afs/kautils.h>
37 /* afs_sia_log logs to the standard sialog. */
39 afs_sia_log(char *fmt, ...)
43 sia_log("AFS", fmt, args);
47 #if defined(AFS_KERBEROS_ENV)
48 extern char *ktc_tkt_string();
51 /* afs_siad_debug gives more detailed debugging information for AFS
52 * than I want to put into the regular sialog.
56 #define DEBUG_FILE "/var/adm/afssialog"
57 /* Modify VERS to ensure you're testing with the current libafssiad.so.
58 * To make SIA recognize a new library, touch /etc/sia/matrix.conf.
61 static void afs_siad_debug(char *fmt, ...)
70 /* Only print if file exists. */
71 if (stat(DEBUG_FILE, &sbuf)<0)
74 if ((fp=fopen(DEBUG_FILE, "a")) == NULL)
81 fprintf(fp, "%s %s: ", VERS, when);
83 vfprintf(fp, fmt, args);
91 /* siad_init - Once per reboot processing goes here. */
97 /* malloc any needed space required over the authentication session here. */
98 int siad_ses_init(SIAENTITY *entity, int pkgind)
103 /* We set the pwd entry in siad_ses_authent if we succeed in authenticating.
104 * Otherwise the BSD mechanism will incur a core dump.
106 int siad_ses_estab(sia_collect_func_t *collect, SIAENTITY *entity, int pkgind)
111 int siad_ses_launch(sia_collect_func_t *collect, SIAENTITY *entity, int pkgind)
116 /* Free up space malloc'd in siad_ses_init() */
117 int siad_ses_release(SIAENTITY *entity, int pkgind)
122 int siad_get_groups(struct sia_context *context, const char *username,
123 gid_t *buf, int *numgroups, int maxgroups)
125 afs_siad_debug("siad_get_groups returning failure.\n");
129 /* Print the reason we failed to authenticate. */
130 static void afs_siad_authent_print_reason(sia_collect_func_t *collect,
133 unsigned char err_msg[128];
136 (void) sprintf(err_msg, "Unable to authenticate to AFS because %s",
138 sia_warning(collect, err_msg);
142 /* afs_siad_get_name_password
144 * Common code for siad_ses_authent and siad_ses_reauthent. Gather name and
145 * password if required.
148 * collect - prompt collection function.
149 * entity - SIA entity
150 * got_pass - set to 1 if we gather'd the password ourselves.
154 * SIADFAIL - failed to malloc, calling routine should return SIADFAIL.
155 * SIADSUCESS - name and password have been collected (maybe not by us).
156 * SIADFAIL | SIADSTOP - calling routine should return.
159 afs_siad_get_name_password(sia_collect_func_t *collect,SIAENTITY * entity,
165 struct prompt_t prompts[2];
170 if ((!entity->name) || (!(*entity->name))) {
171 entity->name = malloc(SIANAMEMIN+1);
172 if(entity->name == NULL) {
173 afs_siad_debug("afs_siad_get_name_password: failed to malloc name.\n");
177 *(entity->name) = '\0';
180 if ((!entity->password) || (!(*entity->password))) {
181 entity->password = malloc(SIAMXPASSWORD+1);
182 if(entity->password == NULL) {
183 afs_siad_debug("afs_siad_get_name_password: failed to malloc password.\n");
187 *(entity->password) = '\0';
191 if (need_name || need_pass) {
192 if (!collect || !entity->colinput) {
197 prompts[0].prompt = (unsigned char*)"login: ";
198 prompts[0].result = (unsigned char*)entity->name;
199 prompts[0].min_result_length = 1;
200 prompts[0].max_result_length = SIANAMEMIN;
201 prompts[0].control_flags = SIAPRINTABLE;
205 prompts[n_prompts].prompt = (unsigned char*)"Password:";
206 prompts[n_prompts].result = (unsigned char*)entity->password;
207 prompts[n_prompts].min_result_length = 0;
208 prompts[n_prompts].max_result_length = SIAMXPASSWORD;
209 prompts[n_prompts].control_flags = SIARESINVIS;
213 code = (*collect)(0, SIAFORM, (uchar_t *)"", n_prompts, prompts);
215 code = (*collect)(240, SIAONELINER, (uchar_t *)"", 1, prompts);
216 if (code != SIACOLSUCCESS) {
217 code = SIADFAIL | SIADSTOP;
221 *got_pass = need_pass;
227 entity->name = (char*)0;
230 free(entity->password);
231 entity->password = (char*)0;
238 * Authenticate user for AFS.
240 * Rules on when to authenticate, from the AFS SysAdmin Guide:
241 * 1) If no entry in password file, try the authentication.
242 * 2) If '*' in password file, don't attempt to authenticate.
243 * NOTE: If enhanced security is turned on, '*' means to check the data base
244 * for the encrypted password.
245 * 3) If passwd field is not 13 characters long, try AFS authentication.
246 * 4) If passwd field is 13 characters, try to authenticate.
248 * 1) Don't try to authenticate if '*' in password field.
249 * 2) Use "Entry AFS Password" if password field is not 13 charaters long.
250 * This really isn't possible if the CDE login is being used since it
251 * prints it's own prompts.
253 * This is an integrated login environement. So I do not print any AFS
254 * specific login messages.
256 * entityhdl->colinput == 1 means the collect function can be used to prompt
257 * for input. If it's 0, then it can only be used to print messages.
258 * For this case, one also has to test for a non-null collect function.
260 * DCE, AFS, BSD is the proper order to do the authentication. Generally
261 * speaking AFS should come just before BSD which is last. The reason is that
262 * if some other mechanism succeeds in authenticating it will probably want to
263 * set the entity->pwd field to something other than /etc/passwd.
265 int siad_ses_authent(sia_collect_func_t *collect, SIAENTITY *entity,
266 int siastat, int pkgind)
270 char *reason; /* returned by authenticate. */
271 int password_expires = -1;
272 struct passwd *pwd = (struct passwd*)0;
273 extern struct passwd *getpwnam();
275 code = afs_siad_get_name_password(collect, entity, &got_pass);
276 if (code != SIADSUCCESS)
279 pwd = getpwnam(entity->name);
281 /* Only authenticate if user is in /etc/passwd. */
285 if ((pwd->pw_passwd[0] == '*') && (pwd->pw_passwd[1] == '\0')) {
286 afs_siad_debug("siad_ses_authent: refusing to authenticate\n");
291 code = ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION | KA_USERAUTH_DOSETPAG,
293 (char*)0, /* instance */
294 (char*)0, /* realm */
302 afs_siad_debug("siad_sis_authent: auth1 failure: %s\n", reason);
311 entity->pwd = (struct passwd*)malloc(sizeof(struct passwd));
316 memset((void*)entity->pwd, '\0', sizeof(struct passwd));
317 if (sia_make_entity_pwd(pwd, entity) != SIASUCCESS) {
318 afs_siad_debug("siad_ses_authent: Can't set pwd into entity.\n");
324 /* Set PASSWORD_EXPIRES env variable if necessary */
325 if (password_expires >= 0 && password_expires < 255) {
327 sprintf(sbuffer, "%d", password_expires);
328 (void)setenv("PASSWORD_EXPIRES", sbuffer, 1);
331 #if defined(AFS_KERBEROS_ENV)
334 if ( chown(ktc_tkt_string(), pwd->pw_uid, pwd->pw_gid) < 0 )
335 afs_siad_debug("siad_ses_authent fails - krb chown.\n");
339 afs_siad_debug("siad_ses_authent returning success.\n");
340 afs_sia_log("siad_ses_authent returning success.\n");
344 afs_sia_log("siad_ses_authent fails, code=%d.\n", code);
345 afs_siad_debug("siad_ses_authent fails, code=%d.\n", code);
351 /* siad_ses_reauthent.
352 * Used for such things as as locking/unlocking terminal. This implies
353 * authenticate, but do not set a pag. The oher differences is that we
354 * accept vouching from other mechanism.
356 * Note the dtsession collects the password itself and will always pass it
357 * in. Also, colinput is typically false in this case as well as collect
360 int siad_ses_reauthent(sia_collect_func_t *collect, SIAENTITY *entity,
361 int siastat, int pkgind)
365 char *reason; /* returned by authenticate. */
366 struct passwd *pwd = (struct passwd*)0;
367 extern struct passwd *getpwnam();
369 if (siastat == SIADSUCCESS)
372 code = afs_siad_get_name_password(collect, entity, &got_pass);
373 if (code != SIADSUCCESS)
376 pwd = getpwnam(entity->name);
382 code = ka_VerifyUserPassword(KA_USERAUTH_VERSION, entity->name,
383 (char*)0, /* instance */
384 (char*)0, /* realm */
390 afs_siad_debug("siad_sis_reauthent: auth failure: %s\n", reason);
399 entity->pwd = (struct passwd*)malloc(sizeof(struct passwd));
404 memset((void*)entity->pwd, '\0', sizeof(struct passwd));
405 if (sia_make_entity_pwd(pwd, entity) != SIASUCCESS) {
406 afs_siad_debug("siad_ses_reauthent: Can't set pwd into entity.\n");
412 afs_siad_debug("siad_ses_reauthent returning success.\n");
413 afs_sia_log("siad_ses_reauthent returning success.\n");
417 afs_sia_log("siad_ses_reauthent fails, code=%d.\n", code);
418 afs_siad_debug("siad_ses_reauthent fails, code=%d.\n", code);
422 int siad_chk_invoker(void)
424 afs_siad_debug("siad_chk_invoker returning failure.\n");
428 int siad_ses_suauthent(sia_collect_func_t *collect, SIAENTITY *entity,
429 int siastat, int pkgind)
431 afs_siad_debug("siad_ses_suauthent returning failure.\n");
436 int siad_chg_finger(sia_collect_func_t *collect, const char *username,
437 int argc, char *argv[])
439 afs_siad_debug("siad_chg_finger returning failure.\n");
443 int siad_chg_password(sia_collect_func_t *collect, const char *username,
444 int argc, char *argv[])
446 afs_siad_debug("siad_chg_passwd returning failure.\n");
450 int siad_chg_shell(sia_collect_func_t *collect, const char *username,
451 int argc, char *argv[])
453 afs_siad_debug("siad_chg_shell returning failure.\n");
457 int siad_getpwent(struct passwd *result, char *buf, int bufsize,
458 struct sia_context *context)
460 afs_siad_debug("siad_getpwent returning failure.\n");
464 int siad_getpwuid(uid_t uid, struct passwd *result, char *buf, int bufsize,
465 struct sia_context *context)
468 afs_siad_debug("siad_getpwuid returning failure.\n");
472 int siad_getpwnam(const char *name, struct passwd *result, char *buf,
473 int bufsize, struct sia_context *context)
475 afs_siad_debug("siad_ses_getpwnam returning failure.\n");
479 int siad_setpwent(struct sia_context *context)
481 afs_siad_debug("siad_ses_setpwent returning failure.\n");
485 int siad_endpwent(struct sia_context *context)
487 afs_siad_debug("siad_ses_endpwent returning failure.\n");
491 int siad_getgrent(struct group *result, char *buf, int bufsize,
492 struct sia_context *context)
494 afs_siad_debug("siad_ses_getgrent returning failure.\n");
498 int siad_getgrgid(gid_t gid, struct group *result, char *buf, int bufsize,
499 struct sia_context *context)
501 afs_siad_debug("siad_ses_getgrgid returning failure.\n");
505 int siad_getgrnam(const char *name, struct group *result, char *buf,
506 int bufsize, struct sia_context *context)
508 afs_siad_debug("siad_ses_getgrnam returning failure.\n");
512 int siad_setgrent(struct sia_context *context)
514 afs_siad_debug("siad_ses_setgrent returning failure.\n");
518 int siad_endgrent(struct sia_context *context)
520 afs_siad_debug("siad_ses_endgrent returning failure.\n");
524 int siad_chk_user(const char *logname, int checkflag)
526 afs_siad_debug("siad_ses_chk_user returning success.\n");
532 /* These are not in the current implementation. */
533 void siad_ses_toggle_privs(SIAENTITY *entity, int pkgind, int elevate)
535 afs_siad_debug("siad_ses_toggle_privs.\n");
540 void siad_ses_update_audit_record(SIAENTITY *entity, int pkgind, int event,
541 char *tokenp, char **datap, int *used,
544 afs_siad_debug("siad_ses_update_audit_record.\n");