Return-Path: Delivered-To: apmail-hadoop-common-commits-archive@www.apache.org Received: (qmail 823 invoked from network); 4 Mar 2011 04:28:36 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 4 Mar 2011 04:28:36 -0000 Received: (qmail 15559 invoked by uid 500); 4 Mar 2011 04:28:36 -0000 Delivered-To: apmail-hadoop-common-commits-archive@hadoop.apache.org Received: (qmail 15530 invoked by uid 500); 4 Mar 2011 04:28:36 -0000 Mailing-List: contact common-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: common-dev@hadoop.apache.org Delivered-To: mailing list common-commits@hadoop.apache.org Received: (qmail 15405 invoked by uid 99); 4 Mar 2011 04:28:35 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Mar 2011 04:28:35 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Mar 2011 04:28:31 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 56BB12388C3E; Fri, 4 Mar 2011 04:28:10 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1077550 [5/5] - in /hadoop/common/branches/branch-0.20-security-patches: ./ src/core/org/apache/hadoop/security/ src/native/ src/native/lib/ src/native/src/org/apache/hadoop/io/compress/zlib/ src/native/src/org/apache/hadoop/security/ Date: Fri, 04 Mar 2011 04:28:09 -0000 To: common-commits@hadoop.apache.org From: omalley@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110304042810.56BB12388C3E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: hadoop/common/branches/branch-0.20-security-patches/src/native/configure.ac URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/native/configure.ac?rev=1077550&r1=1077549&r2=1077550&view=diff ============================================================================== --- hadoop/common/branches/branch-0.20-security-patches/src/native/configure.ac (original) +++ hadoop/common/branches/branch-0.20-security-patches/src/native/configure.ac Fri Mar 4 04:28:09 2011 @@ -86,15 +86,16 @@ AC_SUBST([JNI_CPPFLAGS]) dnl Check for zlib headers AC_CHECK_HEADERS([zlib.h zconf.h], AC_COMPUTE_NEEDED_DSO(z,HADOOP_ZLIB_LIBRARY), AC_MSG_ERROR(Zlib headers were not found... native-hadoop library needs zlib to build. Please install the requisite zlib development package.)) +dnl Check for headers needed by the native Group resolution implementation +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h], [], AC_MSG_ERROR(Some system headers not found... please ensure their presence on your platform.)) + # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST # Checks for library functions. AC_CHECK_FUNCS([memset]) -AC_CONFIG_FILES([Makefile - src/org/apache/hadoop/io/compress/zlib/Makefile - lib/Makefile]) +AC_CONFIG_FILES([Makefile]) AC_OUTPUT # Added: hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c?rev=1077550&view=auto ============================================================================== --- hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c (added) +++ hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/JniBasedUnixGroupsMapping.c Fri Mar 4 04:28:09 2011 @@ -0,0 +1,110 @@ +/** + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "org_apache_hadoop_security_JniBasedUnixGroupsMapping.h" +#include "org_apache_hadoop.h" + +#define CHECK_ERROR_AND_RETURN() \ +{\ + if (error == ENOMEM) {\ + THROW(env, "java/lang/OutOfMemoryError", NULL);\ + }\ + if (error == ENOENT) {\ + THROW(env, "java/io/IOException", "No entry for user");\ + }\ + freeObjs(grpBuf, groups, env, juser, cuser);\ + return NULL;\ +} + +JNIEXPORT jobjectArray JNICALL +Java_org_apache_hadoop_security_JniBasedUnixGroupsMapping_getGroupForUser +(JNIEnv *env, jobject jobj, jstring juser) { + void freeObjs(char *grpBuf, gid_t *groups, JNIEnv *env, jstring juser, + const char *cuser); + extern int getGroupIDList(const char *user, int *ngroups, gid_t **groups); + extern int getGroupDetails(gid_t group, char **grpBuf); + + char *grpBuf = NULL; + const char *cuser = (*env)->GetStringUTFChars(env, juser, NULL); + if (cuser == NULL) { + return NULL; + } + + /*Get the number of the groups, and their IDs, this user belongs to*/ + gid_t *groups = NULL; + int ngroups = 0; + int error = getGroupIDList(cuser, &ngroups, &groups); + if (error != 0) { + CHECK_ERROR_AND_RETURN(); + } + + jobjectArray jgroups = (jobjectArray)(*env)->NewObjectArray(env, ngroups, + (*env)->FindClass(env, "java/lang/String"), NULL); + if (jgroups == NULL) { + freeObjs(grpBuf, groups, env, juser, cuser); + THROW(env, "java/lang/OutOfMemoryError", NULL); + return NULL; + } + + /*Iterate over the groupIDs and get the group structure for each*/ + int i = 0; + for (i = 0; i < ngroups; i++) { + error = getGroupDetails(groups[i],&grpBuf); + if (error != 0) { + CHECK_ERROR_AND_RETURN(); + } + jstring jgrp = (*env)->NewStringUTF(env, ((struct group*)grpBuf)->gr_name); + if (jgrp == NULL) { + freeObjs(grpBuf, groups, env, juser, cuser); + THROW(env, "java/lang/OutOfMemoryError", NULL); + return NULL; + } + (*env)->SetObjectArrayElement(env, jgroups,i,jgrp); + free(grpBuf); + grpBuf = NULL; + } + + freeObjs(grpBuf, groups, env, juser, cuser); + return jgroups; +} + +void freeObjs(char *grpBuf, gid_t *groups, JNIEnv *env, jstring juser, const char *cuser ) { + if (groups != NULL) { + free(groups); + groups = NULL; + } + if (grpBuf != NULL) { + free(grpBuf); + grpBuf = NULL; + } + (*env)->ReleaseStringUTFChars(env, juser, cuser); +} Added: hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/getGroup.c URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/getGroup.c?rev=1077550&view=auto ============================================================================== --- hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/getGroup.c (added) +++ hadoop/common/branches/branch-0.20-security-patches/src/native/src/org/apache/hadoop/security/getGroup.c Fri Mar 4 04:28:09 2011 @@ -0,0 +1,176 @@ +/** + * 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. + */ +#include +#include +#include +#include +#include +#include +#include + +/*Helper functions for the JNI implementation of unix group mapping service*/ + + +/** + * Gets the group IDs for a given user. The groups argument is allocated + * internally, and it contains the list of groups. The ngroups is updated to + * the number of groups + * Returns 0 on success (on success, the caller must free the memory allocated + * internally) + */ +int getGroupIDList(const char *user, int *ngroups, gid_t **groups) { + *ngroups = 0; + char *pwbuf = NULL; + *groups = NULL; + /*Look up the password database first*/ + int error = getPW(user, &pwbuf); + if (error != 0) { + if (pwbuf != NULL) { + free(pwbuf); + } + return error; + } + struct passwd *pw = (struct passwd*)pwbuf; + int ng = 0; + /*Get the groupIDs that this user belongs to*/ + if (getgrouplist(user, pw->pw_gid, NULL, &ng) < 0) { + *ngroups = ng; + *groups = (gid_t *) malloc(ng * sizeof (gid_t)); + if (!*groups) { + free(pwbuf); + return ENOMEM; + } + if (getgrouplist(user, pw->pw_gid, *groups, &ng) < 0) { + free(pwbuf); + free(*groups); + *groups = NULL; + return ENOENT; + } + } + free(pwbuf); + return 0; +} + +/** + * Gets the group structure for a given group ID. + * The grpBuf argument is allocated internally and it contains the + * struct group for the given group ID. + * Returns 0 on success (on success, the caller must free the memory allocated + * internally) + */ +int getGroupDetails(gid_t group, char **grpBuf) { + struct group * grp = NULL; + size_t currBufferSize = sysconf(_SC_GETGR_R_SIZE_MAX); + *grpBuf = NULL; + char *buf = (char*)malloc(sizeof(char) * currBufferSize); + + if (!buf) { + return ENOMEM; + } + int error; + for (;;) { + error = getgrgid_r(group, (struct group*)buf, + buf + sizeof(struct group), + currBufferSize - sizeof(struct group), &grp); + if(error != ERANGE) { + break; + } + free(buf); + currBufferSize *= 2; + buf = malloc(sizeof(char) * currBufferSize); + if(!buf) { + return ENOMEM; + } + } + if(!grp && !error) { + free(buf); + return ENOENT; + } else if (error) { + free(buf); + return error; + } + *grpBuf = buf; + return 0; +} + +/** + * Gets the password database entry for a given user. + * The pwbuf argument is allocated internally and it contains the + * broken out fields for the password database entry + * Returns 0 on success (on success, the caller must free the memory allocated + * internally). + */ +int getPW(const char *user, char **pwbuf) { + struct passwd *pwbufp = NULL; + size_t currBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX); + *pwbuf = NULL; + char *buf = (char*)malloc(sizeof(char) * currBufferSize); + + if (!buf) { + return ENOMEM; + } + int error; + + for (;;) { + error = getpwnam_r(user, (struct passwd*)buf, buf + sizeof(struct passwd), + currBufferSize - sizeof(struct passwd), &pwbufp); + if (error != ERANGE) { + break; + } + free(buf); + currBufferSize *= 2; + buf = (char*)malloc(sizeof(char) * currBufferSize); + if (!buf) { + return ENOMEM; + } + } + if (!pwbufp && !error) { + free(buf); + return ENOENT; + } else if (error) { + free(buf); + return error; + } + *pwbuf = buf; + return 0; +} + +#undef TESTING + +#ifdef TESTING +int main(int argc, char **argv) { + int ngroups; + gid_t *groups = NULL; + char *user = "ddas"; + if (argc == 2) user = argv[1]; + int error = getGroupIDList(user, &ngroups, &groups); + if (error != 0) { + printf("Couldn't obtain grp for user %s", user); + return; + } + int i; + for (i = 0; i < ngroups; i++) { + char *grpbuf = NULL; + error = getGroupDetails(groups[i], &grpbuf); + printf("grps[%d]: %s ",i, ((struct group*)grpbuf)->gr_name); + free(grpbuf); + } + free(groups); + return 0; +} +#endif