RANGER-842: modified to create a separate module for PAM credential validation
Signed-off-by: rmani <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/5ba4831f Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/5ba4831f Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/5ba4831f Branch: refs/heads/master Commit: 5ba4831f3654c0df5f789c62f3850d075cdd278c Parents: 42d8db5 Author: sneethiraj <[email protected]> Authored: Fri Jun 24 00:28:53 2016 -0400 Committer: rmani <[email protected]> Committed: Mon Jul 11 15:09:24 2016 -0700 ---------------------------------------------------------------------- LICENSE.txt | 1 + pom.xml | 15 ++++ src/main/assembly/usersync.xml | 9 +++ unixauthnative/pom.xml | 2 +- unixauthnative/src/main/c/credValidator.c | 89 ++++++--------------- unixauthpam/.gitignore | 3 + unixauthpam/pom.xml | 55 +++++++++++++ unixauthpam/src/main/c/pamCredValidator.c | 104 +++++++++++++++++++++++++ unixauthservice/scripts/setup.py | 7 ++ 9 files changed, 219 insertions(+), 66 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/LICENSE.txt ---------------------------------------------------------------------- diff --git a/LICENSE.txt b/LICENSE.txt index 4789a24..2877b1f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -245,6 +245,7 @@ This product includes Block UI v1.1.1 (https://github.com/dreamerslab/jquery.msg This product includes Sizzle (http://sizzlejs.com/ - MIT license), Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors This product includes ES5 15.5.4.20 (https://github.com/kriskowal/es5-shim - MIT license), Copyright 2009, 2010 Kristopher Michael Kowal. This product includes PURE CSS GUI ICONS 1.0.1(http://nicolasgallagher.com/pure-css-gui-icons/ - Dual licensed under MIT and GNU GPLv2), by Nicolas Gallagher +This product includes libpam4j 1.8 (https://github.com/kohsuke/libpam4j - MIT license), Copyright Kohsuke Kawaguchi. http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index e3e15d9..7a91614 100644 --- a/pom.xml +++ b/pom.xml @@ -187,6 +187,7 @@ <kafka.version>0.10.0.0</kafka.version> <kms.httpcomponents.httpclient.version>4.3.6</kms.httpcomponents.httpclient.version> <knox.gateway.version>0.6.0</knox.gateway.version> + <libpam4j.version>1.8</libpam4j.version> <local.lib.dir>${project.basedir}/../lib/local</local.lib.dir> <log4j.version>1.2.17</log4j.version> <metrics.core.version>3.0.2</metrics.core.version> @@ -238,6 +239,20 @@ <module>unixauthnative</module> </modules> </profile> + <profile> + <id>linux-pam</id> + <activation> + <os> + <family>linux</family> + </os> + <file> + <exists>/usr/include/security/pam_appl.h</exists> + </file> + </activation> + <modules> + <module>unixauthpam</module> + </modules> + </profile> </profiles> <distributionManagement> <repository> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/src/main/assembly/usersync.xml ---------------------------------------------------------------------- diff --git a/src/main/assembly/usersync.xml b/src/main/assembly/usersync.xml index 2f7bea7..66cf3dd 100644 --- a/src/main/assembly/usersync.xml +++ b/src/main/assembly/usersync.xml @@ -120,6 +120,15 @@ <include>credValidator.*</include> </includes> </fileSet> + <fileSet> + <directoryMode>755</directoryMode> + <fileMode>755</fileMode> + <outputDirectory>/native</outputDirectory> + <directory>unixauthpam/target</directory> + <includes> + <include>pamCredValidator.*</include> + </includes> + </fileSet> <fileSet> <directoryMode>755</directoryMode> <outputDirectory>/</outputDirectory> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/unixauthnative/pom.xml ---------------------------------------------------------------------- diff --git a/unixauthnative/pom.xml b/unixauthnative/pom.xml index 70d1469..62aa4e2 100644 --- a/unixauthnative/pom.xml +++ b/unixauthnative/pom.xml @@ -46,7 +46,7 @@ </source> </sources> <linkerEndOptions> - <linkerEndOption>-lpam</linkerEndOption> + <linkerEndOption>-lcrypt</linkerEndOption> </linkerEndOptions> </configuration> </plugin> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/unixauthnative/src/main/c/credValidator.c ---------------------------------------------------------------------- diff --git a/unixauthnative/src/main/c/credValidator.c b/unixauthnative/src/main/c/credValidator.c index ab19080..d706a93 100644 --- a/unixauthnative/src/main/c/credValidator.c +++ b/unixauthnative/src/main/c/credValidator.c @@ -14,91 +14,50 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - /* - You need to add the following (or equivalent) to the - /etc/pam.d/ranger-remote file: - # check authorization - auth required pam_unix.so - account required pam_unix.so - */ - #include <stdio.h> -#include <stdarg.h> #include <unistd.h> #include <stdlib.h> #include <pwd.h> +#include <shadow.h> #include <string.h> #include <sys/types.h> -#include <security/pam_appl.h> - -int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { - if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) { - fprintf(stderr, "ERROR: Unexpected PAM conversation '%d/%s'\n", msg[0]->msg_style, msg[0]->msg); - return PAM_CONV_ERR; - } - if (!appdata_ptr) { - fprintf(stderr, "ERROR: No password available to conversation!\n"); - return PAM_CONV_ERR; - } - *resp = calloc(num_msg, sizeof(struct pam_response)); - if (!*resp) { - fprintf(stderr, "ERROR: Out of memory!\n"); - return PAM_CONV_ERR; - } - (*resp)[0].resp = strdup((char *) appdata_ptr); - (*resp)[0].resp_retcode = 0; - - return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR); -} - -struct pam_conv conv = { pamconv, NULL }; +#include <crypt.h> int main(int ac, char **av, char **ev) { char username[64] ; char password[64] ; char line[512] ; - - int retval; - pam_handle_t *pamh = NULL; + struct passwd *pwp; + struct spwd *spwd ; fgets(line,512,stdin) ; - sscanf(line, "LOGIN:%s %s",username,password) ; - conv.appdata_ptr = (char *) password; - retval = pam_start("ranger-remote", username, &conv, &pamh); - if (retval != PAM_SUCCESS) { - /* why expose this? */ - fprintf(stdout, "FAILED: [%s] does not exists.\n", username) ; - exit(1); - } + sscanf(line, "LOGIN:%s %s",username,password) ; - retval = pam_authenticate(pamh, 0); - if (retval != PAM_SUCCESS) { - fprintf(stdout, "FAILED: Password did not match.\n") ; - exit(1); - } + pwp = getpwnam(username) ; - /* authorize */ - retval = pam_acct_mgmt(pamh, 0); - if (retval != PAM_SUCCESS) { - fprintf(stdout, "FAILED: [%s] is not authorized.\n", username) ; - exit(1); + if (pwp == (struct passwd *)NULL) { + fprintf(stdout, "FAILED: [%s] does not exists.\n", username) ; + exit(1) ; } + + spwd = getspnam(pwp->pw_name) ; - /* establish the requested credentials */ - if ((retval = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) { - fprintf(stdout, "FAILED: Error setting credentials for [%s].\n", username) ; - exit(1); + if (spwd == (struct spwd *)NULL) { + fprintf(stdout, "FAILED: unable to get (shadow) password for %s\n", username) ; + exit(1) ; } - - /* not opening a session, as logout has not been implemented as a remote service */ - fprintf(stdout, "OK:\n") ; - - if (pamh) { - pam_end(pamh, retval); + else { + char *gen = crypt(password,spwd->sp_pwdp) ; + if (strcmp(spwd->sp_pwdp,gen) == 0) { + fprintf(stdout, "OK:\n") ; + exit(0); + } + else { + fprintf(stdout, "FAILED: Password did not match.\n") ; + exit(1) ; + } } - exit(0) ; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/unixauthpam/.gitignore ---------------------------------------------------------------------- diff --git a/unixauthpam/.gitignore b/unixauthpam/.gitignore new file mode 100644 index 0000000..02f68bb --- /dev/null +++ b/unixauthpam/.gitignore @@ -0,0 +1,3 @@ +/target/ +/bin/ +.settings/ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/unixauthpam/pom.xml ---------------------------------------------------------------------- diff --git a/unixauthpam/pom.xml b/unixauthpam/pom.xml new file mode 100644 index 0000000..73a7cb1 --- /dev/null +++ b/unixauthpam/pom.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.ranger</groupId> + <artifactId>ranger</artifactId> + <version>0.6.0-SNAPSHOT</version> + <relativePath>..</relativePath> + </parent> + <artifactId>pamCredValidator</artifactId> + <packaging>uexe</packaging> + <name>PAM Authenticator</name> + <description>PAM authentication service</description> + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>native-maven-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <compilerStartOptions> + <compilerStartOption>${commonCompilerOptions}</compilerStartOption> + </compilerStartOptions> + <sources> + <source> + <directory>src/main/c</directory> + <includes> + <include>**/*.c</include> + </includes> + </source> + </sources> + <linkerEndOptions> + <linkerEndOption>-lpam</linkerEndOption> + </linkerEndOptions> + </configuration> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/unixauthpam/src/main/c/pamCredValidator.c ---------------------------------------------------------------------- diff --git a/unixauthpam/src/main/c/pamCredValidator.c b/unixauthpam/src/main/c/pamCredValidator.c new file mode 100644 index 0000000..ab19080 --- /dev/null +++ b/unixauthpam/src/main/c/pamCredValidator.c @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + You need to add the following (or equivalent) to the + /etc/pam.d/ranger-remote file: + # check authorization + auth required pam_unix.so + account required pam_unix.so + */ + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <stdlib.h> +#include <pwd.h> +#include <string.h> +#include <sys/types.h> +#include <security/pam_appl.h> + +int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) { + fprintf(stderr, "ERROR: Unexpected PAM conversation '%d/%s'\n", msg[0]->msg_style, msg[0]->msg); + return PAM_CONV_ERR; + } + if (!appdata_ptr) { + fprintf(stderr, "ERROR: No password available to conversation!\n"); + return PAM_CONV_ERR; + } + *resp = calloc(num_msg, sizeof(struct pam_response)); + if (!*resp) { + fprintf(stderr, "ERROR: Out of memory!\n"); + return PAM_CONV_ERR; + } + (*resp)[0].resp = strdup((char *) appdata_ptr); + (*resp)[0].resp_retcode = 0; + + return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR); +} + +struct pam_conv conv = { pamconv, NULL }; + +int main(int ac, char **av, char **ev) +{ + char username[64] ; + char password[64] ; + char line[512] ; + + int retval; + pam_handle_t *pamh = NULL; + + fgets(line,512,stdin) ; + sscanf(line, "LOGIN:%s %s",username,password) ; + conv.appdata_ptr = (char *) password; + + retval = pam_start("ranger-remote", username, &conv, &pamh); + if (retval != PAM_SUCCESS) { + /* why expose this? */ + fprintf(stdout, "FAILED: [%s] does not exists.\n", username) ; + exit(1); + } + + retval = pam_authenticate(pamh, 0); + if (retval != PAM_SUCCESS) { + fprintf(stdout, "FAILED: Password did not match.\n") ; + exit(1); + } + + /* authorize */ + retval = pam_acct_mgmt(pamh, 0); + if (retval != PAM_SUCCESS) { + fprintf(stdout, "FAILED: [%s] is not authorized.\n", username) ; + exit(1); + } + + /* establish the requested credentials */ + if ((retval = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) { + fprintf(stdout, "FAILED: Error setting credentials for [%s].\n", username) ; + exit(1); + } + + /* not opening a session, as logout has not been implemented as a remote service */ + fprintf(stdout, "OK:\n") ; + + if (pamh) { + pam_end(pamh, retval); + } + + exit(0) ; +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5ba4831f/unixauthservice/scripts/setup.py ---------------------------------------------------------------------- diff --git a/unixauthservice/scripts/setup.py b/unixauthservice/scripts/setup.py index 4b93a40..eb7e8f8 100755 --- a/unixauthservice/scripts/setup.py +++ b/unixauthservice/scripts/setup.py @@ -62,6 +62,7 @@ confDistDirName = join(installPropDirName, confDistBaseDirName) #ugsyncLogFolderName = join(logFolderName, 'usersync') nativeAuthFolderName = join(installPropDirName, 'native') nativeAuthProgramName = join(nativeAuthFolderName, 'credValidator.uexe') +pamAuthProgramName = join(nativeAuthFolderName, 'pamCredValidator.uexe') usersyncBaseDirFullName = join(rangerBaseDirName, usersyncBaseDirName) confFolderName = join(usersyncBaseDirFullName, confBaseDirName) localConfFolderName = join(installPropDirName, confBaseDirName) @@ -489,6 +490,12 @@ def main(): else: print "WARNING: Unix Authentication Program (%s) is not available for setting chmod(4550), chown(%s:%s) " % (nativeAuthProgramName, "root", groupName) + if isfile(pamAuthProgramName): + os.chown(pamAuthProgramName, rootOwnerId, groupId) + os.chmod(pamAuthProgramName, 04555) + else: + print "WARNING: Unix Authentication Program (%s) is not available for setting chmod(4550), chown(%s:%s) " % (pamAuthProgramName, "root", groupName) + write_env_files("logdir", logFolderName, ENV_LOGDIR_FILE); write_env_files("RANGER_USERSYNC_HADOOP_CONF_DIR", hadoop_conf, ENV_HADOOP_CONF_FILE); os.chown(os.path.join(confBaseDirName, ENV_LOGDIR_FILE),ownerId,groupId)
