Back to index

im-sdk  12.3.91
iwrap.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 #ifdef HAVE_CONFIG_H
00044 #include <config.h>
00045 #endif
00046 
00047 #ifdef HAVE_LIBWRAP
00048 #include <syslog.h>
00049 int allow_severity = LOG_DEBUG;
00050 int deny_severity = LOG_WARNING;
00051 #include <tcpd.h>
00052 #endif
00053 
00054 #ifdef HAVE_PAM
00055 #include <security/pam_appl.h>
00056 #endif
00057 
00058 #ifdef HAVE_UNIX_SOCKET
00059 #include <sys/types.h>
00060 #include <sys/socket.h>
00061 #include <pwd.h>
00062 #endif
00063 
00064 #include <stdlib.h>
00065 #include <string.h>
00066 #include "iwrap.h"
00067 
00068 int permit_access(
00069     const char *cmdname,
00070     int h
00071 )
00072 {
00073 #ifdef HAVE_LIBWRAP
00074     struct request_info req;
00075 
00076     request_init(&req, RQ_DAEMON, cmdname, RQ_FILE, h, 0);
00077     fromhost(&req);
00078 
00079     if (!hosts_access(&req)) return 0;
00080 #endif
00081 
00082     return 1;
00083 }
00084 
00085 #ifdef HAVE_PAM
00086 static int
00087 local_conv_for_pam(
00088     int num_msg,
00089     const struct pam_message **msg,
00090     struct pam_response **resp,
00091     void *appdata_ptr
00092 )
00093 {
00094 /* When PAM would like to make a conversation, this function
00095    will silence it :-P. */
00096     int i;
00097     int style;
00098     struct pam_response *rs;
00099 
00100     rs = (struct pam_response*) malloc(num_msg * sizeof(struct pam_response));
00101     if (!rs) return PAM_CONV_ERR;
00102     for (i = 0;i < num_msg;i++)    {
00103        style = msg[i]->msg_style;
00104        if (style == PAM_PROMPT_ECHO_OFF) {
00105            rs[i].resp_retcode = 0;
00106            rs[i].resp = strdup((char*) appdata_ptr);
00107        } else {
00108            rs[i].resp_retcode = 0;
00109            rs[i].resp = NULL;
00110        }
00111     }
00112     *resp = rs;
00113 
00114     return PAM_SUCCESS;
00115 }
00116 #endif /* HAVE_PAM */
00117 
00118 int
00119 authenticate_with_pam(
00120     const char *user,
00121     const char *password,
00122     const char *command_name,
00123     const char *hostname
00124 )
00125 {
00126 #ifdef HAVE_PAM
00127     struct pam_conv cv;
00128     pam_handle_t *ph = NULL;
00129     int ret;
00130 
00131     cv.conv = local_conv_for_pam;
00132     cv.appdata_ptr = (void*) password;
00133     ret = pam_start(command_name, user, &cv, &ph);
00134     if (ret != PAM_SUCCESS) goto fail;
00135 
00136     if (hostname) {
00137        ret = pam_set_item(ph, PAM_RHOST, hostname);
00138        if (ret != PAM_SUCCESS) goto fail;
00139     }
00140 
00141     /* Account checking. */
00142     ret = pam_acct_mgmt(ph, PAM_SILENT);
00143     if (ret != PAM_SUCCESS) goto fail;
00144 
00145     /* Password checking. */
00146     if (password) {
00147        ret = pam_set_item(ph, PAM_AUTHTOK, password);
00148        /* 
00149           Don't check the return value for the PAM not supporting
00150           PAM_AUTHTOK.
00151           if (ret != PAM_SUCCESS) goto fail;
00152        */
00153        ret = pam_authenticate(ph, PAM_SILENT);
00154        if (ret != PAM_SUCCESS) goto fail;
00155     }
00156 
00157     pam_end(ph, ret);
00158     return 1;
00159 fail:
00160     pam_end(ph, ret);
00161     return 0;
00162 #else /* not HAVE_PAM */
00163     return 0;
00164 #endif /* not HAVE_PAM */
00165 }
00166 
00167 #ifdef HAVE_UNIX_SOCKET
00168 int
00169 authenticate_with_unix(
00170     int sock, 
00171     const char *user,
00172     const char *password,
00173     const char *command_name,
00174     const char *hostname) {
00175     uid_t uid = -1;
00176     struct passwd *pass;
00177 #ifdef HAVE_GETPEEREID
00178     /* OpenBSD */
00179     git_t gid;
00180 
00181     if (getpeereid(sock, &uid, &gid) != 0) {
00182       return 0;
00183     }
00184 
00185 #elif defined(SO_PEERCRED)
00186     /* Linux */
00187     struct ucred peercred;
00188     socklen_t peer_len = sizeof(peercred);
00189 
00190     if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &peer_len) != 0) {
00191       return 0;
00192     }
00193 
00194     uid = peercred.uid;
00195 
00196 #elif defined (HAVE_GETPWNAM)
00197     struct passwd *passwd_r;
00198     passwd_r = getpwnam(user);
00199     if (passwd_r == NULL)
00200       return 0;
00201     uid = passwd_r->pw_uid;
00202 #else
00203 #error "don't know how to authenticate unix domain"
00204     return -1;
00205 #endif
00206 #  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
00207     {
00208 /* for getpwuid_r */
00209 #ifndef NSS_BUFLEN_PASSWD
00210 #define NSS_BUFLEN_PASSWD 1024
00211 #endif
00212        struct passwd pass_buf;
00213        char buf[NSS_BUFLEN_PASSWD];
00214 
00215 #    ifdef HAVE_POSIX_GETPWUID_R
00216        if (getpwuid_r(uid, &pass_buf, buf, NSS_BUFLEN_PASSWD, &pass) != 0) {
00217            return 0;
00218        }
00219 #else
00220        if ((pass = getpwuid_r(uid, &pass_buf, buf, NSS_BUFLEN_PASSWD))
00221            == NULL) {
00222          return 0;
00223        }
00224 #endif
00225     }
00226 #else
00227     if ((pass = getpwuid(uid)) == NULL) {
00228        return 0;
00229     }
00230 #endif /* HAVE_GETPWUID_R */
00231 
00232     if (!strcmp(user, pass->pw_name)) {
00233        return 1;
00234     }
00235     return 0;
00236 }
00237 #endif /* HAVE_UNIX_SOCKET */
00238 
00239 /* Local Variables: */
00240 /* c-file-style: "iiim-project" */
00241 /* End: */