Login.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:16k
- /* $Id: Login.c++,v 1.12 2008/04/05 19:09:56 faxguy Exp $ */
- /*
- * Copyright (c) 1995-1996 Sam Leffler
- * Copyright (c) 1995-1996 Silicon Graphics, Inc.
- * HylaFAX is a trademark of Silicon Graphics
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- #include "HylaFAXServer.h"
- #include "Sys.h"
- #include <unistd.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <pwd.h>
- #if HAS_CRYPT_H
- #include <crypt.h>
- #endif
- void
- HylaFAXServer::loginRefused(const char* why)
- {
- if (++loginAttempts >= maxLoginAttempts) {
- reply(530, "Login incorrect (closing connection).");
- logNotice("Repeated login failures for user %s from %s [%s]"
- , (const char*) the_user
- , (const char*) remotehost
- , (const char*) remoteaddr
- );
- dologout(0);
- } else {
- reply(530, "User %s access denied.", (const char*) the_user);
- logNotice("HylaFAX LOGIN REFUSED (%s) FROM %s [%s], %s"
- , why
- , (const char*) remotehost
- , (const char*) remoteaddr
- , (const char*) the_user
- );
- }
- }
- /*
- * USER command. Sets global passwd state if named
- * account exists and is acceptable; sets askpasswd if a
- * PASS command is expected. If logged in previously,
- * need to reset state. User account must be accessible
- * from client host according to the contents of the
- * userAccessFile.
- */
- void
- HylaFAXServer::userCmd(const char* name)
- {
- if (IS(LOGGEDIN)) {
- if (IS(PRIVILEGED) && the_user == name) {// revert to unprivileged mode
- state &= ~S_PRIVILEGED;
- reply(230, "User %s logged in.", name);
- return;
- }
- end_login();
- }
- the_user = name;
- state &= ~S_PRIVILEGED;
- adminWd = "*"; // make sure no admin privileges
- passWd = "*"; // just in case...
- if (checkUser(name)) {
- if (passWd != "") {
- state |= S_WAITPASS;
- reply(331, "Password required for %s.", name);
- /*
- * Delay before reading passWd after first failed
- * attempt to slow down password-guessing programs.
- */
- if (loginAttempts)
- sleep(loginAttempts);
- } else
- login(230);
- } else
- loginRefused("user denied");
- }
- #ifdef HAVE_PAM
- int
- pamconv(int num_msg, STRUCT_PAM_MESSAGE **msg, struct pam_response **resp, void *appdata)
- {
- /*
- * This PAM conversation function expects that the PAM modules
- * being used will only have one message. If this expectation
- * is not met then this will fail, and this will need modification
- * in order to work.
- */
- char *password =(char*) appdata;
- struct pam_response* replies;
- if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
- return PAM_CONV_ERR;
- if (password == NULL) {
- /*
- * Solaris doesn't have PAM_CONV_AGAIN defined.
- */
- #ifdef PAM_CONV_AGAIN
- return PAM_CONV_AGAIN;
- #else
- return PAM_CONV_ERR;
- #endif
- }
- replies=(struct pam_response*)calloc(num_msg, sizeof(struct pam_response));
- replies[0].resp = password;
- replies[0].resp_retcode = 0;
- *resp = replies;
- return (PAM_SUCCESS);
- }
- #endif //HAVE_PAM
- bool
- HylaFAXServer::pamIsAdmin(const char* user)
- {
- bool retval = false;
- #ifdef HAVE_PAM
- int i;
- static struct group* grinfo = getgrnam(admingroup);
- const char *curruser = (user == NULL ? the_user.c_str() : user);
- if (grinfo != NULL) {
- for (i=0; grinfo->gr_mem[i] != NULL; i++) {
- if (strcmp(curruser, grinfo->gr_mem[i]) == 0) retval = true;
- }
- }
- #endif //HAVE_PAM
- return(retval);
- }
- /**
- * ldapCheck
- * function checks if user with selected login and password exists in LDAP
- * param user [IN] - pointer to string containing user login
- * param pass [IN] - pointer to string containing user password
- * return true if user exists
- */
- bool
- HylaFAXServer::ldapCheck(const char* user, const char* pass)
- {
- bool retval = false;
- #ifdef HAVE_LDAP
- int err = 0, i = 0;
- char* filter = new char[255];
- snprintf(filter, 255, "uid=%s", user);
- LDAPMessage* pEntries;
- LDAPMessage* pEntry;
- struct berval **p_arr_values;
- struct berval s_UserPasswd;
- char* sLDAPUserDN = new char[255];
- LDAP* p_LDAPConn;
- bool bValidUser = false;
- /*
- * See if ldapServerUri has a value.
- * If not, disable using LDAP support.
- */
- if (strlen(ldapServerUri) == 0) {
- retval = false;
- return retval;
- }
- /*
- * Build the User DN using the LDAP Base value
- * from the config file and the supplied username
- */
- strcpy(sLDAPUserDN, "cn=");
- strcat(sLDAPUserDN, user);
- strcat(sLDAPUserDN, ",");
- strcat(sLDAPUserDN, ldapBaseDN);
- strcat(sLDAPUserDN, "