Pam.allow

From: RaghuNath L(Raghu) (lraghunath@Lucent.Com)
Date: Tue Jun 11 2002 - 03:29:53 EDT


Hello Managers,
I have been trying this c program and this shell script ,i have succesfully
compiled the pam_asp_allow.so1.
But this script needs innetgr which i am not able to figure out how to go
about.
Can any body help me in this regard.
I will Summarize.
Regards
Raghu

#!/bin/csh
if ( $USER != "" ) then
         set hostname=`/usr/bin/hostname`
         innetgr <Ypmap name> $hostname
         if ( $status == "10" ) then
                 ypmatch $hostname <ypmapname>| grep -w $LOGNAME >/dev/null
                 if ( $status != "0" ) then
                         echo "SORRY: You are not authorized to use this
system..."
                         logout
                 endif
         endif
endif

* Copyright (c) 1999 by Sun Microsystems, Inc.
* All rights reserved.
*
* Modified: Robert Colon <frcolon@ti.com> 07Nov2000
* Organization: Dallas ASP Design Computing, Texas Instruments, Inc.
* Changes: Correct logic
* Replace innetgr with innetgrfrc
* Put 'allow' files in /etc/pam directory
* Allow 'root' login regardless of contents of /etc/pam/users.allow
* Add /etc/pam/hosts.allow just for hosts
* Allow login for all users if no /etc/pam/users.allow
* Allow login for all hosts if no /etc/pam/hosts.allow
* Allow rsh for all users from local host (for LSF)
* Name change from pam_netgroup to pam_asp_allow
* Correct link/owner tests on 'allow' files
* Syslog and debug at every fail point
* Allow Unix sysadmin group(14) login regardless of users.allow
* Remove 'exact'
* Add /etc/pam/users.deny /etc/pam/hosts.deny
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
* OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF SUN
* MICROSYSTEMS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SUN MICROSYSTEMS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THE SOFTWARE PROVIDED
* HEREUNDER IS ON AN "AS IS" BASIS, AND SUN MICROSYSTEMS, INC. HAS NO
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
* MODIFICATIONS.
*
*/
#pragma ident "@(#)pam_asp_allow.c 1.7 00/11/11 SMI"
/*
* pam_asp_allow.c - restrict access based on username or netgroup
* Used to overcome the perfomance problems of using
* passwd_compat in nsswitch.conf
*
* Compile:
*
* cc pam_asp_allow.c -o pam_asp_allow.so.1 -Kpic -G
*
* To restrict logins to a host:
*
* 1. Install:
*
* cp pam_asp_allow.so.1 /usr/lib/security
* chmod 444 /usr/lib/security/pam_asp_allow.so.1
* chown root /usr/lib/security/pam_asp_allow.so.1
*
* 2. Update /etc/pam.conf Account management section:
*
* #
* # Account management
* #
* login account required /usr/lib/security/pam_asp_allow.so.1 user host
* login account required /usr/lib/security/pam_unix.so.1
* dtlogin account required /usr/lib/security/pam_asp_allow.so.1 user host
* dtlogin account required /usr/lib/security/pam_unix.so.1
* #
* cron account required /usr/lib/security/pam_unix.so.1
* other account required /usr/lib/security/pam_asp_allow.so.1 user host
* other account required /usr/lib/security/pam_unix.so.1
*
* To see debug printed to 'tmpf' add the keyword 'debug' ahead of 'user' above
* Never write debug to stderr/stdout as it blocks returns from 'rsh'
*
* At this point all logins are still permitted. I.e. the installation of
* the pam_asp_allow.so.1 module and the update to pam.conf does not
* affect allowed logins. The next steps implement login restrictions.
*
* Note: login has been authenticated before this module starts
*
* If you create a new copy of pam.conf make sure it is owned by root. If
* not, no one will be able to login including root.
*
* 3. To restrict logins by users use /etc/pam/users.allow file (not a link).
* Each line contains a 'user' type netgroup (e.g. @asic_admins) or the
* name of an account to be granted login access (e.g. joeb).
*
* Must be owned by root.
*
* Do not use any whitespace on the line. Comments beginning '#' allowed.
*
* 'root' is allowed access and does not need to be listed in the file.
*
* Any login except 'login' that originates from a running process inside
* the local machine is permitted regardless of the contents of this file.
*
* An empty file allows only 'root' and group 14 logins.
*
* NOTE: for all telnet's rsh's ftp's - 'rhost' is fully qualified
* (if rhost == localhost.defaultdomain, PAM_SUCCESS)
* for su - 'rhost' is unqualified
* (if rhost == localhost, PAM_SUCCESS)
* for local 'login' - 'rhost' is NULL
* (hostok=1, 'username' must be allowed)
* for command line 'login' - 'rhost' is NULL
* (hostok=1, 'username' must be allowed)
* for dtlogin - 'rhost' is ":0"
* (hostok=1, 'username' must be allowed)
* for remote dtlogin - 'rhost' is "remote_host:0"
* (:0 stripped off 'rhost', unqualified 'rhost' must be allowed,
* 'username' must be allowed)
*
* 4. To restrict logins from hosts use /etc/pam/hosts.allow file (not a link).
* Each line contains a 'host' type netgroup (e.g. @tcpwrap) or fully
* qualified hostname to be granted remote login access (e.g.
* host.dal.asp.ti.com). Use unqualified names to allow remote dtlogins.
*
* Not recommended.
*
* 5. To deny login to a 'user' type netgroup or to an account, use the
* /etc/pam/users.deny file (not a link).
*
* Use same format as for "users.allow".
*
* An empty file is the same as a non-existent file.
*
* A user account found in this file denies login access regardless of
* the contents of "users.allow".
*
* 6. To deny login to a 'host' type netgroup or to a host, use the
* /etc/pam/hosts.deny file (not a link).
*
* Not recommended.
*
*/
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <netdb.h>
#include <malloc.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <pwd.h>
#define tmpf "/tmp/pammessages"
#define domainf "/etc/defaultdomain"
#define ROOT "root"
#define dot "."
#define SYSADMIN 46
int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
FILE *allowfl;
FILE *TMP;
FILE *DOMAIN;
char *netgroup;
char *rhost = NULL;
char buf[BUFSIZ];
char domain[BUFSIZ];
char localhost[BUFSIZ];
char LOCALHOST[BUFSIZ];
char *username = NULL;
char *ALLOW_FILE[] = {"/etc/pam/users.allow","/etc/pam/hosts.allow",
"/etc/pam/users.deny" ,"/etc/pam/hosts.deny"};
struct stat allowfl_stat;
int buflen = 0;
int check_user = 0;
int check_host = 0;
int check_exact = 0;
int userok = 0;
int hostok = 0;
int DEBUG = 1;
int i, j;
int filecnt;
gid_t gid;
struct passwd *passwdx;
if (DEBUG) {
TMP = fopen("/tmp/pam_debug_log_file","a");
fprintf(TMP,"ARG: %d %s %s\n",argc,argv[0], argv[1]);
fclose(TMP);
TMP = fopen("/tmp/pam_debug_log_file","a");
setbuf(TMP,NULL);
}
for (i = 0; i < argc; ++i) {
if (strcasecmp(argv[i], "user") == 0) {
check_user = 1;
if (DEBUG) fprintf(TMP,"pam_asp_allow: 'user' argument found\n");
} else if (strcasecmp(argv[i], "host") == 0) {
check_host = 1;
if (DEBUG) fprintf(TMP,"pam_asp_allow: 'host' argument found\n");
} else if (strcasecmp(argv[i], "debug") == 0) {
DEBUG = 1;
/*TMP = fopen(tmpf,"a");
setbuf(TMP,NULL);*/
fprintf(TMP,"\npam_asp_allow: start\n");
}
else {
syslog(LOG_ERR, "pam_asp_allow: illegal option %s\n", argv[i]);
if (DEBUG) fprintf(TMP,"pam_asp_allow: illegal option %s\n",argv[i]);
}
}
fprintf(TMP, "Came out of for loop\n");
if (! check_user) userok = 1;
if (! check_host) hostok = 1;
fprintf(TMP, "Entering user loop\n");
username = (char *)malloc(25);
i = pam_get_item(pamh, PAM_USER, (void**)&username);
fprintf(TMP, "status = %d\n",i);
if(i != PAM_SUCCESS) {
fprintf(TMP, "User loop failure\n");
syslog(LOG_ERR, "pam_asp_allow: pam_get_item(,,&username) fail\n");
if (DEBUG) {
fprintf(TMP, "pam_asp_allow: pam_get_item(,,&username) fail\n");
fclose(TMP);
}
return (PAM_SERVICE_ERR);
}
pam_get_item(pamh, PAM_RHOST, (void**)&rhost);
fprintf(TMP, "returned from PAM_RHOST call\n");
if(rhost == NULL) rhost = "localhost";
if (DEBUG)
fprintf(TMP,"pam_asp_allow: %s login from %s attempted\n",username,rhost);
/* check to see if login is from 'root' and allow it */
if (strcasecmp(username,ROOT) == 0 ) {
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: %s login from %s allowed\n",username,rhost);
fclose(TMP);
}
return (PAM_SUCCESS);
}
/* check to see if login is from inside local host and allow it */
gethostname(localhost,BUFSIZ);
strcpy(LOCALHOST,localhost);
if ((DOMAIN = fopen(domainf, "r")) == NULL) {
syslog(LOG_ERR,"pam_asp_allow: Unable to open %s\n",domainf);
if (DEBUG) fprintf(TMP,"pam_asp_allow: unable to open %s\n",domainf);
}
else {
while (fgets(domain, BUFSIZ-1, DOMAIN) != NULL ) {
buflen=strlen(domain);
domain[buflen - 1] = '\0';
}
/* build fully qualified local hostname */
strcat(LOCALHOST,dot);
strcat(LOCALHOST,domain);
}
if (DEBUG)
fprintf(TMP,"pam_asp_allow: local host name = %s %s\n",localhost,LOCALHOST);
/* local hostname, remote rhost comparison */
if ( strcasecmp(localhost,rhost) == 0 || strcasecmp(LOCALHOST,rhost) == 0 ) {
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: local hostname == remote hostname, "
"login allowed\n");
fclose(TMP);
}
return (PAM_SUCCESS);
}
else if (DEBUG)
fprintf(TMP,"pam_asp_allow: local hostname != remote hostname, "
"continue\n");
/* if login is from console, set hostok but make user pass login test */
if ( strlen(rhost) == 0 || rhost[0] == ':' ) {
if (DEBUG) fprintf(TMP,"pam_asp_allow: console login detected (%s), "
"hostok=1, continue\n",rhost);
hostok=1;
}
/* if login is from remote host via dtlogin, rhost==remotehost:0 */
/* remove ":0", require that an unqualified rhost be allowed */
buflen = strlen(rhost);
if ( rhost[buflen-1] == '0' && rhost[buflen-2] == ':' ) {
rhost[buflen-2] = '\0';
if (DEBUG) fprintf(TMP,"pam_asp_allow: remote dtlogin(%s) "
"strip off ':0'\n",rhost);
}
/* get group id for account, allow login if SYSADMIN unix group */
if ( passwdx = getpwnam(username) ) {
gid = passwdx->pw_gid;
if ( gid == SYSADMIN ) {
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: gid=%d, SYSADMIN, login allowed\n",gid);
fclose(TMP);
}
return(PAM_SUCCESS);
}
else if (DEBUG) fprintf(TMP,"pam_asp_allow: gid = %d, continue\n",gid);
}
else if (DEBUG)
fprintf(TMP, "pam_asp_allow: ERROR: cannot find user(%s)\n",username);
for (filecnt = 0; filecnt < 4; filecnt++) {
if ( filecnt == 0 && userok ) continue;
if ( filecnt == 1 && hostok ) continue;
if ( filecnt == 2 && !userok ) continue;
if ( filecnt == 3 && !hostok ) continue;
if (lstat(ALLOW_FILE[filecnt], &allowfl_stat) < 0) {
/* if no users.allow, permit any user to login */
if ( filecnt == 0 ) {
userok=1;
if (DEBUG)
fprintf(TMP,"pam_asp_allow: no %s file, permit all users to login\n",
ALLOW_FILE[filecnt]);
continue;
}
/* if no hosts.allow, permit any host to login */
if ( filecnt == 1 ) {
hostok=1;
if (DEBUG)
fprintf(TMP,"pam_asp_allow: no %s file, permit all hosts to login\n",
ALLOW_FILE[filecnt]);
continue;
}
/* if no users.deny or hosts.deny, do nothing */
continue;
}
if (! S_ISREG(allowfl_stat.st_mode) || /* symbolic link */
(allowfl_stat.st_nlink > 1) || /* hard links */
(allowfl_stat.st_uid > 0)) { /* not owned by root */
syslog(LOG_ERR, "pam_asp_allow: "
"%s is/has links or isn't owned by root\n", ALLOW_FILE[filecnt]);
if(DEBUG) {
fprintf(TMP, "pam_asp_allow: "
"%s is/has links or isn't owned by root\n", ALLOW_FILE[filecnt]);
fclose(TMP);
}
return (PAM_SERVICE_ERR);
}
if ((allowfl = fopen(ALLOW_FILE[filecnt], "r")) == NULL) {
syslog(LOG_ERR, "pam_asp_allow: cannot read %s\n", ALLOW_FILE[filecnt]);
if(DEBUG) {
fprintf(TMP, "pam_asp_allow: cannot read %s\n", ALLOW_FILE[filecnt]);
fclose(TMP);
}
return (PAM_SERVICE_ERR);
}
while (fgets(buf, BUFSIZ-1, allowfl) != NULL) {
buflen = strlen(buf);
if (buflen > 1) {
buf[buflen - 1] = '\0';
buflen -= 1;
} else {
continue;
}
if (buf[0] == '#')
continue;
if ((buf[0] == '@') && (buf[1] != '\0')) {
if ((netgroup = (char *)malloc(buflen)) == NULL) {
syslog(LOG_ERR, "pam_asp_allow: malloc error\n");
if(DEBUG) {
fprintf(TMP, "pam_asp_allow: malloc error\n");
fclose(TMP);
}
return (PAM_SERVICE_ERR);
}
for (i = 1, j = 0; i < buflen; ++i, ++j) {
netgroup[j] = buf[i];
}
netgroup[j] = '\0';
if (DEBUG)
fprintf(TMP, "pam_asp_allow: checking netgroup: %s\n", netgroup);
if (check_user &&
((! userok && filecnt==0) || (userok && filecnt==2))) {
userok = innetgrfrc(netgroup, NULL, username, NULL) == 1;
if (DEBUG) {
if (userok) {
fprintf(TMP,"pam_asp_allow: %s found in netgroup %s in %s\n",
username,netgroup,ALLOW_FILE[filecnt]);
}
else
fprintf(TMP,"pam_asp_allow: %s NOT found in netgroup %s in %s\n",
username,netgroup,ALLOW_FILE[filecnt]);
}
if ( filecnt==2 ) {
if ( userok ) {
/* deny login access */
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: %s login denied\n",
username);
fclose(TMP);
}
syslog(LOG_ERR,"pam_asp_allow: %s login denied\n",
username);
return(PAM_AUTH_ERR);
}
else userok = 1;
}
if ( userok && filecnt==0 ) continue;
}
if (check_host &&
((! hostok && filecnt==1) || ( hostok && filecnt==3))) {
hostok = innetgrfrc(netgroup, rhost, NULL, NULL) == 1;
if (DEBUG) {
if (hostok) {
fprintf(TMP,"pam_asp_allow: %s found in netgroup %s in %s\n",
rhost,netgroup,ALLOW_FILE[filecnt]);
}
else
fprintf(TMP,"pam_asp_allow: %s NOT found in netgroup %s in %s\n",
rhost,netgroup,ALLOW_FILE[filecnt]);
}
if ( filecnt==3 ) {
if ( hostok ) {
/* deny login access */
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: %s login from %s denied\n",
username,rhost);
fclose(TMP);
}
syslog(LOG_ERR,"pam_asp_allow: %s login from %s denied\n",
username,rhost);
return(PAM_AUTH_ERR);
}
else hostok = 1;
}
if ( hostok && filecnt==1 ) continue;
}
}
else {
if (filecnt == 0 || filecnt == 2) {
/* check for explicit user */
if (DEBUG)
fprintf(TMP, "pam_asp_allow: checking user: %s\n", buf);
if (strcmp(buf, username) == 0) {
if (DEBUG)
fprintf(TMP, "pam_asp_allow: found user %s in %s\n",
buf,ALLOW_FILE[filecnt]);
userok = (filecnt==0);
if ( !userok ) {
/* deny login access */
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: %s login denied\n",
username);
fclose(TMP);
}
syslog(LOG_ERR,"pam_asp_allow: %s login denied\n",
username);
return(PAM_AUTH_ERR);
}
continue;
}
} else {
/* check for explicit host */
if (DEBUG)
fprintf(TMP, "pam_asp_allow: checking host: %s\n", buf);
if (strcmp(buf, rhost) == 0) {
if (DEBUG)
fprintf(TMP, "pam_asp_allow: found host %s in %x\n",
buf,ALLOW_FILE[filecnt]);
hostok = (filecnt==1);
if ( !hostok ) {
/* deny login access */
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: %s login from %s denied\n",
username,rhost);
fclose(TMP);
}
syslog(LOG_ERR,"pam_asp_allow: %s login from %s denied\n",
username,rhost);
return(PAM_AUTH_ERR);
}
continue;
}
}
}
}
}
if (userok && hostok) {
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: found user & host\n");
fprintf(TMP,"pam_asp_allow: %s login from %s allowed\n",username,rhost);
fclose(TMP);
}
return (PAM_SUCCESS);
}
if (DEBUG) {
fprintf(TMP,"pam_asp_allow: %s login from %s disallowed\n",username,rhost);
fclose(TMP);
}
syslog(LOG_ERR, "pam_asp_allow: "
"%s login from %s disallowed\n",username,rhost);
return (PAM_AUTH_ERR);
}
int innetgrfrc(const char *netgroup, const char *machine,
const char *user, const char *domain)
{
/*
* Author: Robert Colon <frcolon@ti.com> 20Mar2000
* Function: a version of 'innetgr' that works (ignore domain)
*/
char cnull[] = "NULL";
char *mp, *up, *dp;
if ( ! machine ) machine = cnull;
if ( ! user ) user = cnull;
/* find members of netgroup */
setnetgrent(netgroup);
while ( getnetgrent(&mp, &up, &dp) ) {
if ( ! mp ) mp = cnull;
if ( ! up ) up = cnull;
if ( strcasecmp(machine,mp) == 0 && strcasecmp(user,up) == 0 ) return 1;
}
return 0;
}
_______________________________________________
sunmanagers mailing list
sunmanagers@sunmanagers.org
http://www.sunmanagers.org/mailman/listinfo/sunmanagers



This archive was generated by hypermail 2.1.7 : Wed Apr 09 2008 - 23:24:26 EDT