2 Replies Latest reply on Dec 21, 2004 10:24 PM by janoss

    NIS Authentication

    janoss

      Is it possible to use the JAAS JndiLoginModule to authenticate users against an NIS server.

      I read in other posts that JBoss does not recognize the JndoLoginModule. If this is the case, can anyone suggest some alernative approaches?

      thanks in advance.

        • 1. Re: NIS Authentication
          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

            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>
            -----------------------