All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hudson.security.PAMSecurityRealm Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *
 * Copyright (c) 2004-2012, Oracle Corporation
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *
 *  Kohsuke Kawaguchi, Winston Prakash
 *
 *******************************************************************************/ 

package hudson.security;

import hudson.EnvVars;
import hudson.Functions;
import hudson.model.Descriptor;
import hudson.Util;
import hudson.Extension;
import hudson.util.FormValidation;
import java.util.ArrayList;
import org.eclipse.hudson.jna.NativeAccessException;
import org.eclipse.hudson.jna.NativeUtils;
import java.util.Arrays;
import java.util.List;

import org.kohsuke.stapler.DataBoundConstructor;
import java.util.Set;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * {@link SecurityRealm} that uses Unix PAM authentication.
 *
 * @author Kohsuke Kawaguchi
 * @since 1.282
 */
public class PAMSecurityRealm extends AbstractPasswordBasedSecurityRealm {

    public final String serviceName;

    @DataBoundConstructor
    public PAMSecurityRealm(String serviceName) {
        serviceName = Util.fixEmptyAndTrim(serviceName);
        if (serviceName == null) {
            serviceName = "sshd"; // use sshd as the default
        }
        this.serviceName = serviceName;
    }

    @Override
    protected UserDetails authenticate(String username, String password) throws AuthenticationException {
        try {

            Set grps = NativeUtils.getInstance().pamAuthenticate(serviceName, username, password);
            List groups = new ArrayList();
            for (String g : grps) {
                groups.add(new GrantedAuthorityImpl(g));
            }
            groups.add(AUTHENTICATED_AUTHORITY);
            EnvVars.setHudsonUserEnvVar(username);
            return new User(username, "", true, true, true, true, groups);
        } catch (NativeAccessException exc) {
            throw new BadCredentialsException(exc.getMessage(), exc);
        }
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        try {
            if (!NativeUtils.getInstance().checkUnixUser(username)) {
                throw new UsernameNotFoundException("No such Unix user: " + username);
            }
        } catch (NativeAccessException exc) {
            throw new DataAccessException("Failed to find Unix User", exc) {
            };
        }

        // return some dummy instance
        return new User(username, "", true, true, true, true,
                Arrays.asList(new GrantedAuthority[]{AUTHENTICATED_AUTHORITY}));
    }

    @Override
    public GroupDetails loadGroupByGroupname(final String groupname) throws UsernameNotFoundException, DataAccessException {
        try {
            if (!NativeUtils.getInstance().checkUnixGroup(groupname)) {
                throw new UsernameNotFoundException("No such Unix group: " + groupname);
            }
        } catch (NativeAccessException exc) {
            throw new DataAccessException("Failed to find Unix Group", exc) {
            };
        }

        return new GroupDetails() {
            @Override
            public String getName() {
                return groupname;
            }
        };
    }

    public static final class DescriptorImpl extends Descriptor {

        @Override
        public String getDisplayName() {
            return Messages.PAMSecurityRealm_DisplayName();
        }

        public FormValidation doTest() {
            try {
                String message = NativeUtils.getInstance().checkPamAuthentication();
                if (message.startsWith("Error:")) {
                    return FormValidation.error(message.replaceFirst("Error:", ""));
                } else {
                    return FormValidation.ok(message);
                }
            } catch (NativeAccessException exc) {
                return FormValidation.error("Native Support for PAM Authentication not available.");
            }
        }
    }

    @Extension
    public static DescriptorImpl install() {
        if (!Functions.isWindows()) {
            return new DescriptorImpl();
        }
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy