[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

pam_nislistfile (was Re: pam_regex )



On Fri, 14 Nov 1997, Michael K. Johnson wrote:

> People have asked for the pam_nislistfile module before, so I'm quite
> sure that's welcome news.

I've attached the c source. It uses basically the same Makefile as
listfile. Hell, it basically is listfile. I can claim no real credit
for this :)

It is listfile with the group matching taken out and the file reading
loop changed to a yp_matching routine.

..........................
Chris Dent........SysAdmin
...........Kiva Networking
/*
 * by Chris Dent <cdent@kiva.net> for Kiva Networking
 * July 25, 1996.
 * This code shamelessly ripped from the pam_lisfile module
 * and it was ripped from the pam_rootok module.
 * And that is why Linux (and associates) is a great thing.
 */

#define _SVID_SOURCE
#define _BSD_SOURCE
#define __USE_BSD
#define __USE_SVID
#define __USE_MISC
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <syslog.h>
#include <stdarg.h>
#include <string.h>

#include <rpcsvc/ypclnt.h>

#ifdef DEBUG
#include <assert.h>
#endif

/*
 * here, we make a definition for the externally accessible function
 * in this file (this definition is required for static a module
 * but strongly encouraged generally) it is used to instruct the
 * modules include file to define the function prototypes.
 */

#define PAM_SM_AUTH

#include <security/pam_modules.h>

/* some syslogging */

static void _pam_log(int err, const char *format, ...)
{
    va_list args;

    va_start(args, format);
    openlog("PAM-nislistfile", LOG_CONS|LOG_PID, LOG_AUTH);
    vsyslog(err, format, args);
    va_end(args);
    closelog();
}

/* Our own strdup()-style routine */
static char *xstrdup(const char *x)
{
    char *s;
    
    if ((s = (char *) malloc(strlen(x)+1))) {
	strcpy(s,x);
    }
    
    return s;
}

/* --- authentication management functions (only) --- */

/* Constants for apply= parameter */
#define APPLY_TYPE_NULL		0
#define APPLY_TYPE_NONE		1
#define APPLY_TYPE_USER		2
#define APPLY_TYPE_GROUP	3

PAM_EXTERN
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
	int retval, i, citem=0, onerr=PAM_SERVICE_ERR, sense=2;
	const char *citemp;
	char *ifname=NULL;
	char mybuf[256],myval[256];

	char *domainname;
	char *mapentry;
	int yperr;
	int entrylen;

	for(i=0; i < argc; i++) {
		{
			char *junk;
			junk = (char *) malloc(strlen(argv[i])+1);
			if (junk == NULL) {
				return PAM_BUF_ERR;
			}
			strcpy(junk,argv[i]);
			strncpy(mybuf,strtok(junk,"="),255);
			strncpy(myval,strtok(NULL,"="),255);
			free(junk);
		}
		if(!strcmp(mybuf,"onerr"))
				if(!strcmp(myval,"succeed"))
			onerr = PAM_SUCCESS;
				else if(!strcmp(myval,"fail"))
			onerr = PAM_SERVICE_ERR;
				else
			return PAM_SERVICE_ERR;
		else if(!strcmp(mybuf,"sense"))
				if(!strcmp(myval,"allow"))
			sense=0;
		else if(!strcmp(myval,"deny"))
			sense=1;
		else
			return onerr;
		else if(!strcmp(mybuf,"map")) {
			ifname = (char *)malloc(strlen(myval)+1);
			strcpy(ifname,myval);
			_pam_log(LOG_ERR,"Got for map: %s=%s",mybuf, myval);
		} else if(!strcmp(mybuf,"item")) {
			if(!strcmp(myval,"user"))
				citem = PAM_USER;
			else if(!strcmp(myval,"tty"))
				citem = PAM_TTY;
			else if(!strcmp(myval,"rhost"))
				citem = PAM_RHOST;
			else if(!strcmp(myval,"ruser"))
				citem = PAM_RUSER;
			else
				citem = 0;
		} else { 
			_pam_log(LOG_ERR,"Unknown option: %s",mybuf);
			return onerr;
		}
	}


	if(!citem) {
		_pam_log(LOG_ERR,"Unknown item or item not specified");
		return onerr;
	} else if(!ifname) {
		_pam_log(LOG_ERR,"List map not specified");
		return onerr;
	} else if(sense == 2) {
		_pam_log(LOG_ERR,"Unknown sense or sense not specified");
		return onerr;
	}

	retval = pam_get_item(pamh,citem,(const void **)&citemp);
	if(retval != PAM_SUCCESS) {
		return onerr;
	}
	if((citem == PAM_USER) && !citemp) {
		pam_get_user(pamh,&citemp,NULL);
		if (retval != PAM_SUCCESS)
			return PAM_SERVICE_ERR;
	}

	if(!citemp || (strlen(citemp) <= 0)) {
		/* The item was NULL - we are sure not to match */
		return sense?PAM_SUCCESS:PAM_AUTH_ERR;
	}

#ifdef DEBUG
    _pam_log(LOG_INFO,"Got map = %s, item = %d, value = %s, sense = %d",
	     ifname, citem, citemp, sense);
#endif
	/* Do some N[IY]S */
	yp_get_default_domain(&domainname);
	yp_bind(domainname);
	yperr = yp_match(domainname, ifname, citemp, strlen(citemp),
	                 &mapentry, &entrylen);
#ifdef DEBUG
	assert(PAM_SUCCESS == 0);
	assert(PAM_AUTH_ERR != 0);
#endif
	if (yperr) {
		if (yperr != YPERR_KEY) {
			if (onerr == PAM_SERVICE_ERR) {
			/* only report an error if that's considered bad */
				_pam_log(LOG_ERR, "Error opening %s", ifname);
			}
			return onerr;
		} else {
			retval = PAM_AUTH_ERR;
		}
	} else {
		retval = PAM_SUCCESS;
	}
	free(ifname);

	if(retval) {
#ifdef DEBUG
		syslog(LOG_INFO,"Returning %d, retval = %d",
			sense?PAM_AUTH_ERR:PAM_SUCCESS, retval);
#endif
		return sense?PAM_SUCCESS:PAM_AUTH_ERR;
	} else {
#ifdef DEBUG
		syslog(LOG_INFO,"Returning %d, retval = %d",
			sense?PAM_SUCCESS:PAM_AUTH_ERR, retval);
#endif
		return sense?PAM_AUTH_ERR:PAM_SUCCESS;
	}
}

PAM_EXTERN
int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
    return PAM_SUCCESS;
}

#ifdef PAM_STATIC

/* static module data */

struct pam_module _pam_nislistfile_modstruct = {
    "pam_nislistfile",
    pam_sm_authenticate,
    pam_sm_setcred,
    NULL,
    NULL,
    NULL,
    NULL,
};

#endif

/* end of module definition */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] []