-
1. Re: NIS Authentication
janoss Dec 21, 2004 2:41 PM (in response to janoss)I added the JndiLoginModule to my jboss login-config.xml. And setup the "user.provider.url" and "group.provider.url" to point to my NIS server. I have TRACE enabled in the log4j.xml filr for jboss security. All I see in the jboss log is that my login module is being added to the map. Going through the jmx-console I verify that my login-module is indeed loaded with no jboss exceptions.
When I access the protected servlet, I get the login dialog. I type in both valid and invalid usernames, no logs in Jboss, no authentication, the login dialog just pops back. I need knowledge. -
2. Re: NIS Authentication - Simple NIS Custom Login Module
janoss Dec 21, 2004 10:24 PM (in response to janoss)Here is a simple NIS Custom Login Module I discovered. Let me know if you see room for improvement:
---------------------
NISLoginModule.h
---------------------
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class NISLoginModule */
#ifndef _Included_NISLoginModule
#define _Included_NISLoginModule
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: NISLoginModule
* Method: isValid
* Signature: (Ljava/lang/String;Ljava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL Java_NISLoginModule_isValid
(JNIEnv *, jobject, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
------------------------
NISLoginModule.java
------------------------
import java.util.Map;
import java.security.Principal;
import java.security.acl.Group;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
public class NISLoginModule extends UsernamePasswordLoginModule {
private String username;
private String password;
private String principal;
private SimplePrincipal simpleprincipal;
public native boolean isValid(String user, String pass);
static {
System.loadLibrary("jni_nis");
}
public void initialize(Subject subject,
CallbackHandler callbackHandler,
Map sharedState,
Map options) {
super.initialize(subject, callbackHandler, sharedState, options);
String option = (String) options.get("principal");
if (option != null) {
super.log.trace("init principal = " + principal);
principal = option;
simpleprincipal = new SimplePrincipal(principal);
}
}
public boolean login() throws LoginException {
boolean loginOK = false;
String[] info = getUsernameAndPassword();
username = info[0];
password = info[1];
loginOK = isValid(username, password);
if (!loginOK)
throw new LoginException("bad authentification");
super.log.trace("loginOK = " + loginOK);
return super.login();
}
protected Principal getIdentity() {
super.log.trace("getIdentity = " + simpleprincipal);
return simpleprincipal;
}
protected Group[] getRoleSets() throws LoginException {
Group[] roleSets = {new SimpleGroup("Roles")};
roleSets[0].addMember(simpleprincipal);
super.log.trace("getRoleSets = " + roleSets);
return roleSets;
}
protected String getUsersPassword() {
super.log.trace("getUsersPassword = " + password);
return password;
}
}
-------
pam.c
-------
#include <jni.h>
#include "NISLoginModule.h"
#include <security/pam_appl.h>
#include <stdio.h>
int
converse(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
char buf[PAM_MAX_RESP_SIZE];
int i;
data = data;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((*resp = calloc(n, sizeof **resp)) == NULL)
return (PAM_BUF_ERR);
for (i = 0; i < n; ++i) {
resp->resp_retcode = 0;
resp->resp = NULL;
switch (msg->msg_style) {
case PAM_PROMPT_ECHO_OFF:
resp->resp = (char *) data;
if (resp->resp == NULL)
goto fail;
break;
case PAM_PROMPT_ECHO_ON:
fputs(msg->msg, stderr);
if (fgets(buf, sizeof buf, stdin) == NULL)
goto fail;
resp->resp = strdup(buf);
if (resp->resp == NULL)
goto fail;
break;
case PAM_ERROR_MSG:
fputs(msg->msg, stderr);
if (strlen(msg->msg) > 0 &&
msg->msg[strlen(msg->msg) - 1] != '\n')
fputc('\n', stderr);
break;
case PAM_TEXT_INFO:
fputs(msg->msg, stdout);
if (strlen(msg->msg) > 0 &&
msg->msg[strlen(msg->msg) - 1] != '\n')
fputc('\n', stdout);
break;
default:
goto fail;
}
}
return (PAM_SUCCESS);
fail:
while (i)
free(resp[--i]);
free(*resp);
*resp = NULL;
return (PAM_CONV_ERR);
}
JNIEXPORT jboolean JNICALL Java_NISLoginModule_isValid
(JNIEnv * env, jobject obj, jstring user, jstring pass) {
jboolean ret = JNI_FALSE;
pam_handle_t * pamh;
struct pam_conv pamc;
char * username = (*env)->GetStringUTFChars(env, user, 0);
char * password = (*env)->GetStringUTFChars(env, pass, 0);
pamc.conv = converse;
pamc.appdata_ptr = password;
pam_start("su", username, &pamc, &pamh);
if (pam_authenticate(pamh, 0) == PAM_SUCCESS)
ret = JNI_TRUE;
pam_end(pamh, 0);
(*env)->ReleaseStringUTFChars(env, user, username);
(*env)->ReleaseStringUTFChars(env, pass, password);
return ret;
}
---------------------
Configuration
----------------
<application-policy name = "nistest">
<login-module code = "NISLoginModule"
flag = "required"
>
<module-option name="principal">PlainUser</module-option>
</login-module>
</application-policy>
-----------------------