Summary:Pam.allow

From: RaghuNath L(Raghu) <lraghunath_at_Lucent.Com>
Date: Tue Jun 18 2002 - 04:35:32 EDT
Hello ,
This is the function which needs to complied .
To use this you need to have a netgroup like sysadmin,create a map like 
called pamallow put host name first user names separated by ","(semicolon)
This is batter than netgroup where in you can do chown to restricted user 
logins.
at one place you can deny and allow users and hosts.
  I got this information through my friend where this is implemented.
Regards
Raghu
#this innetgr fuction compile only with sun cc.
#include<stdio.h>
#include<netdb.h>

main(int argc, char **argv)
{
int stat;

   if(argc != 3) {
          fprintf(stderr,"Usage: %s netgroup machine\n",argv[0]);
          exit(5);
   }
   stat = innetgr(argv[1],argv[2],NULL,NULL);
   if( stat == 1 ) exit(10);
   exit(0);
}

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`
         /usr/sbin/innetgr <netgroupname> $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.
*
*
* 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
Received on Tue Jun 18 04:46:26 2002

This archive was generated by hypermail 2.1.8 : Thu Mar 03 2016 - 06:42:46 EST