tacacs-F4.0.4.28/sendpass.c (113 lines of code) (raw):

/* * $Id: sendpass.c,v 1.6 2006-12-13 01:11:37 heas Exp $ * * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved * Copyright (c) 1995-1998 by Cisco systems, Inc. * * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that this * copyright and permission notice appear on all copies of the * software and supporting documentation, the name of Cisco Systems, * Inc. not be used in advertising or publicity pertaining to * distribution of the program without specific prior permission, and * notice be given in supporting documentation that modification, * copying and distribution is by permission of Cisco Systems, Inc. * * Cisco Systems, Inc. makes no representations about the suitability * of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS * IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE. */ #include "tac_plus.h" #include "expire.h" static int do_sendpass_fn(); int sendpass_fn(struct authen_data *data) { int status; char *name = data->NAS_id->username; char *port = data->NAS_id->NAS_port; if (sendauth_only) { /* sendpass is disallowed */ report(LOG_ERR, "%s: %s %s sendpass request rejected", session.peer, session.port, name ? name : "<unknown>"); data->status = TAC_PLUS_AUTHEN_STATUS_FAIL; return(0); } if (STREQ(name, DEFAULT_USERNAME)) { data->status = TAC_PLUS_AUTHEN_STATUS_FAIL; status = 0; } else { status = do_sendpass_fn(data); } if (debug) report(LOG_INFO, "sendpass query for '%s' %s from %s %s", name && name[0] ? name : "unknown", port && port[0] ? port : "unknown", session.peer, (data->status == TAC_PLUS_AUTHEN_STATUS_PASS) ? "accepted" : "rejected"); return(status); } /* * Cleartext password information has been requested. Look this up in * the config file. Set authen_data->status. * * Any strings pointed to by authen_data must come from the heap. They * will get freed by the caller. * * Return 0 if data->status is valid, otherwise 1 */ static int do_sendpass_fn(struct authen_data *data) { char *name; char *p; int expired; char *exp_date; char *secret; data->status = TAC_PLUS_AUTHEN_STATUS_FAIL; /* We must have a username */ if (!data->NAS_id->username[0]) { /* choose_authen should have already asked for a username, so this is * a gross error */ data->status = TAC_PLUS_AUTHEN_STATUS_ERROR; data->server_msg = tac_strdup("No username supplied"); report(LOG_ERR, "%s: No username for sendpass_fn", session.peer); return(0); } name = data->NAS_id->username; exp_date = cfg_get_expires(name, TAC_PLUS_RECURSE); /* The user exists. Check the expiration date, if any */ expired = check_expiration(exp_date); switch (expired) { case PW_EXPIRED: data->status = TAC_PLUS_AUTHEN_STATUS_FAIL; data->server_msg = tac_strdup("Password has expired"); return(0); default: data->status = TAC_PLUS_AUTHEN_STATUS_ERROR; data->server_msg = tac_strdup("Bad return value for password " "expiration check"); report(LOG_ERR, "%s: Bogus return value %d from check_expiration", session.peer, expired); return(0); case PW_OK: case PW_EXPIRING: /* The user exists, and has not expired. Return her secret info */ switch (data->type) { case TAC_PLUS_AUTHEN_TYPE_CHAP: secret = cfg_get_chap_secret(name, TAC_PLUS_RECURSE); if (!secret) secret = cfg_get_global_secret(name, TAC_PLUS_RECURSE); break; #ifdef MSCHAP case TAC_PLUS_AUTHEN_TYPE_MSCHAP: secret = cfg_get_mschap_secret(name, TAC_PLUS_RECURSE); if (!secret) secret = cfg_get_global_secret(name, TAC_PLUS_RECURSE); break; #endif /* MSCHAP */ case TAC_PLUS_AUTHEN_TYPE_ARAP: secret = cfg_get_arap_secret(name, TAC_PLUS_RECURSE); if (!secret) secret = cfg_get_global_secret(name, TAC_PLUS_RECURSE); break; case TAC_PLUS_AUTHEN_TYPE_PAP: secret = cfg_get_opap_secret(name, TAC_PLUS_RECURSE); break; default: data->status = TAC_PLUS_AUTHEN_STATUS_ERROR; data->server_msg = tac_strdup("Illegal authentication type"); report(LOG_ERR, "%s: Illegal authentication type %d", session.peer, data->type); return(0); } if (!secret) { data->status = TAC_PLUS_AUTHEN_STATUS_FAIL; data->server_msg = tac_strdup("No secret"); return(0); } p = tac_find_substring("cleartext ", secret); if (!p) { /* Should never happen */ data->status = TAC_PLUS_AUTHEN_STATUS_ERROR; data->server_msg = tac_strdup("Illegal secret format"); report(LOG_ERR, "%s: Illegal secret format %s", session.peer, secret); return(0); } data->server_data = tac_strdup(p); data->server_dlen = strlen(data->server_data); data->status = TAC_PLUS_AUTHEN_STATUS_PASS; if (expired == PW_EXPIRING) { data->server_msg = tac_strdup("Secret will expire soon"); } return(0); } /* never reached */ }