fuse_users.c
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:5k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. #include <pthread.h>
  19. #include <grp.h>
  20. #include <pwd.h>
  21. #include <stdlib.h>
  22. #include "fuse_dfs.h"
  23. #if PERMS
  24. /**
  25.  * getpwuid and getgrgid return static structs so we safeguard the contents
  26.  * while retrieving fields using the 2 structs below.
  27.  * NOTE: if using both, always get the passwd struct firt!
  28.  */
  29. pthread_mutex_t passwdstruct_mutex = PTHREAD_MUTEX_INITIALIZER;
  30. pthread_mutex_t groupstruct_mutex = PTHREAD_MUTEX_INITIALIZER;
  31. #endif
  32. #if PERMS
  33. /**
  34.  * Utility for getting the user making the fuse call in char * form
  35.  * NOTE: if non-null return, the return must be freed by the caller.
  36.  */
  37. char *getUsername(uid_t uid)
  38. {
  39.   //
  40.   // Critical section - protect from concurrent calls in different threads.
  41.   // since the struct below is static.
  42.   // (no returns until end)
  43.   //
  44.   pthread_mutex_lock(&passwdstruct_mutex);
  45.   struct passwd *userinfo = getpwuid(uid);
  46.   char * ret = userinfo && userinfo->pw_name ? strdup(userinfo->pw_name) : NULL;
  47.   pthread_mutex_unlock(&passwdstruct_mutex);
  48.   //
  49.   // End critical section 
  50.   // 
  51.   return ret;
  52. }
  53. /**
  54.  * Cleans up a char ** group pointer
  55.  */
  56. void freeGroups(char **groups, int numgroups) {
  57.   if (groups == NULL) {
  58.     return;
  59.   }
  60.   int i ;
  61.   for (i = 0; i < numgroups; i++) {
  62.     free(groups[i]);
  63.   }
  64.   free(groups);
  65. }
  66. #define GROUPBUF_SIZE 5
  67. char *getGroup(gid_t gid) {
  68.   //
  69.   // Critical section - protect from concurrent calls in different threads.
  70.   // since the struct below is static.
  71.   // (no returns until end)
  72.   //
  73.   pthread_mutex_lock(&groupstruct_mutex);
  74.   struct group* grp = getgrgid(gid);
  75.   char * ret = grp && grp->gr_name ? strdup(grp->gr_name) : NULL;
  76.   //
  77.   // End critical section 
  78.   // 
  79.   pthread_mutex_unlock(&groupstruct_mutex);
  80.   return ret;
  81. }
  82. /**
  83.  * Utility for getting the group from the uid
  84.  * NOTE: if non-null return, the return must be freed by the caller.
  85.  */
  86. char *getGroupUid(uid_t uid) {
  87.   //
  88.   // Critical section - protect from concurrent calls in different threads
  89.   // since the structs below are static.
  90.   // (no returns until end)
  91.   //
  92.   pthread_mutex_lock(&passwdstruct_mutex);
  93.   pthread_mutex_lock(&groupstruct_mutex);
  94.   char *ret = NULL;
  95.   struct passwd *userinfo = getpwuid(uid);
  96.   if (NULL != userinfo) {
  97.     struct group* grp = getgrgid( userinfo->pw_gid);
  98.     ret = grp && grp->gr_name ? strdup(grp->gr_name) : NULL;
  99.   }
  100.   //
  101.   // End critical section 
  102.   // 
  103.   pthread_mutex_unlock(&groupstruct_mutex);
  104.   pthread_mutex_unlock(&passwdstruct_mutex);
  105.   return ret;
  106. }
  107. /**
  108.  * lookup the gid based on the uid
  109.  */
  110. gid_t getGidUid(uid_t uid) {
  111.   //
  112.   // Critical section - protect from concurrent calls in different threads
  113.   // since the struct below is static.
  114.   // (no returns until end)
  115.   //
  116.   pthread_mutex_lock(&passwdstruct_mutex);
  117.   struct passwd *userinfo = getpwuid(uid);
  118.   gid_t gid = userinfo == NULL ? 0 : userinfo->pw_gid;
  119.   //
  120.   // End critical section 
  121.   // 
  122.   pthread_mutex_unlock(&passwdstruct_mutex);
  123.   return gid;
  124. }
  125. /**
  126.  * Utility for getting the groups for the user making the fuse call in char * form
  127.  */
  128. char ** getGroups(uid_t uid, int *num_groups)
  129. {
  130.   char *user = getUsername(uid);
  131.   if (user == NULL)
  132.     return NULL;
  133.   char **groupnames = NULL;
  134.   // see http://www.openldap.org/lists/openldap-devel/199903/msg00023.html
  135.   //#define GETGROUPS_T 1 
  136. #ifdef GETGROUPS_T
  137.   *num_groups = GROUPBUF_SIZE;
  138.   gid_t* grouplist = malloc(GROUPBUF_SIZE * sizeof(gid_t)); 
  139.   assert(grouplist != NULL);
  140.   gid_t* tmp_grouplist; 
  141.   int rtr;
  142.   gid_t gid = getGidUid(uid);
  143.   if ((rtr = getgrouplist(user, gid, grouplist, num_groups)) == -1) {
  144.     // the buffer we passed in is < *num_groups
  145.     if ((tmp_grouplist = realloc(grouplist, *num_groups * sizeof(gid_t))) != NULL) {
  146.       grouplist = tmp_grouplist;
  147.       getgrouplist(user, gid, grouplist, num_groups);
  148.     }
  149.   }
  150.   groupnames = (char**)malloc(sizeof(char*)* (*num_groups) + 1);
  151.   assert(groupnames);
  152.   int i;
  153.   for (i=0; i < *num_groups; i++)  {
  154.     groupnames[i] = getGroup(grouplist[i]);
  155.     if (groupnames[i] == NULL) {
  156.       fprintf(stderr, "error could not lookup group %dn",(int)grouplist[i]);
  157.     }
  158.   } 
  159.   free(grouplist);
  160.   assert(user != NULL);
  161.   groupnames[i] = user;
  162.   *num_groups = *num_groups + 1;
  163. #else
  164.   int i = 0;
  165.   assert(user != NULL);
  166.   groupnames[i] = user;
  167.   i++;
  168.   groupnames[i] = getGroupUid(uid);
  169.   if (groupnames[i]) {
  170.     i++;
  171.   }
  172.   *num_groups = i;
  173. #endif
  174.   return groupnames;
  175. }
  176. #endif