Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lcmaps_utils.c

Go to the documentation of this file.
00001 /*                                                                                                            
00002  * Copyright (c) 2001 EU DataGrid.                                                                             
00003  * For license conditions see http://www.eu-datagrid.org/license.html                                          
00004  *
00005  * Copyright (c) 2001, 2002 by 
00006  *     Martijn Steenbakkers <martijn@nikhef.nl>,
00007  *     David Groep <davidg@nikhef.nl>,
00008  *     NIKHEF Amsterdam, the Netherlands
00009  */
00010 
00017 /*****************************************************************************
00018                             Include header files
00019 ******************************************************************************/
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <unistd.h>
00026 #include <errno.h>
00027 #include <stdarg.h>
00028 #include <gssapi.h>
00029 #include <grp.h>
00030 #include "lcmaps_defines.h"
00031 #include "lcmaps_types.h"
00032 #include "lcmaps_log.h"
00033 
00034 /******************************************************************************
00035                              Define constants
00036 ******************************************************************************/
00037 
00038 /******************************************************************************
00039                           Module specific prototypes
00040 ******************************************************************************/
00041 static char * cred_to_dn(gss_cred_id_t);
00042 static int    fexist(char *);
00043 
00044 
00045 /******************************************************************************
00046 Function:       lcmaps_fill_cred()
00047 Description:    Fill cedential from dn and globus credential
00048 Parameters:
00049                 dn: distinguished name
00050                 cred: globus credential
00051                 lcmaps_cred: pointer to lcmaps_credential
00052 Returns:        0: succes
00053                 1: failure
00054 ******************************************************************************/
00074 int lcmaps_fill_cred(
00075         char * dn,
00076         gss_cred_id_t cred,
00077         lcmaps_cred_id_t * plcmaps_cred
00078 )
00079 {
00080     /* Set the credential pointer */
00081 /*    plcmaps_cred->cred = &cred; */
00082     plcmaps_cred->cred = cred;
00083 
00084     if (cred == GSS_C_NO_CREDENTIAL) /* Empty credential: Fill DN with passed dn */
00085     {
00086         plcmaps_cred->dn = NULL;
00087         if (dn)
00088             plcmaps_cred->dn = strdup(dn);
00089     }
00090     else
00091     {
00092         plcmaps_cred->dn = cred_to_dn(cred);
00093     }
00094     if (plcmaps_cred->dn == NULL)
00095         return 1; /* Cannot find user dn */
00096     return 0;
00097 }
00098 
00099 /******************************************************************************
00100 Function:       lcmaps_release_cred()
00101 Description:    release lcmaps credential
00102 Parameters:
00103                 plcmaps_cred: pointer to lcmaps_credential
00104 Returns:        0: succes
00105                 1: failure
00106 ******************************************************************************/
00117 int lcmaps_release_cred(
00118         lcmaps_cred_id_t * plcmaps_cred
00119 )
00120 {
00121     if (plcmaps_cred == NULL)
00122         return 0;
00123 
00124     if (plcmaps_cred->dn != NULL)
00125         free(plcmaps_cred->dn);
00126     /* Don't release globus credential (not copied) */
00127 
00128     return 0;
00129 }
00130 
00131 /******************************************************************************
00132 Function:       lcmaps_get_dn()
00133 Description:    returns user dn
00134 Parameters:
00135                 lcmaps_cred: lcmaps_credential
00136 Returns:        user dn
00137 ******************************************************************************/
00153 char * lcmaps_get_dn(
00154         lcmaps_cred_id_t lcmaps_cred
00155 )
00156 {
00157     return (lcmaps_cred.dn);
00158 }
00159 
00160 /******************************************************************************
00161 Function:       cred_to_dn() (copied from GLOBUS gatekeeper.c)
00162 Description:    Get the globusid from gssapi
00163 Parameters:
00164                 globus_cred: globus credential
00165 Returns:        globusid string (which could be freeed)
00166 ******************************************************************************/
00178 static char * cred_to_dn(
00179         gss_cred_id_t globus_cred
00180 )
00181 {
00182     char*                         globusid = NULL;
00183     char*                         globusid_tmp = NULL;
00184     gss_name_t                    globus_name = GSS_C_NO_NAME;
00185     gss_buffer_desc               globus_buffer_desc = GSS_C_EMPTY_BUFFER;
00186     gss_buffer_t                  globus_buffer = &globus_buffer_desc;
00187     OM_uint32                     major_status = 0;
00188     OM_uint32                     minor_status = 0;
00189     OM_uint32                     minor_status2 = 0;
00190 
00191     if ((major_status = gss_inquire_cred(&minor_status,
00192                                          globus_cred,
00193                                          &globus_name,
00194                                          NULL, NULL, NULL)) == GSS_S_COMPLETE)
00195     {
00196         major_status = gss_display_name(&minor_status,
00197                                         globus_name, globus_buffer, NULL);
00198         gss_release_name(&minor_status2, &globus_name);
00199     }
00200     /*
00201      * The gssapi_cleartext does not implement gss_inquire_cred,
00202      * so fall back to using environment variable.
00203      */
00204     if (major_status == GSS_S_COMPLETE)
00205     {
00206         globusid = globus_buffer_desc.value;
00207     }
00208     else
00209     {
00210         globusid = getenv("GLOBUSID");
00211         globusid = (globusid ? globusid : "GLOBUSID");
00212     }
00213     globusid_tmp = strdup(globusid);
00214 
00215     if (globus_buffer_desc.value)
00216     {
00217         gss_release_buffer(&minor_status2, globus_buffer);
00218     }
00219     return globusid_tmp;
00220 }
00221 
00222 /******************************************************************************
00223 Function:       lcmaps_genfilename() (copied from GLOBUS gatekeeper.c)
00224 Description:    generate an absolute file name given a starting prefix,
00225                 a relative or absolute path, and a suffix
00226                 Only use prefix if path is relative.
00227 Parameters:
00228 Returns:        a pointer to a string which could be freeded.
00229 ******************************************************************************/
00249 char * lcmaps_genfilename(
00250         char * prefixp,
00251         char * pathp,
00252         char * suffixp
00253 )
00254 {
00255     char * newfilename;
00256     int    prefixl, pathl, suffixl;
00257     char * prefix,  * path, * suffix;
00258 
00259     prefix = (prefixp) ? prefixp : "";
00260     path   = (pathp) ? pathp : "";
00261     suffix  = (suffixp) ? suffixp : "";
00262 
00263     prefixl = strlen(prefix);
00264     pathl   =  strlen(path);
00265     suffixl  =  strlen(suffix); 
00266 
00267     newfilename = (char *) calloc(1, (prefixl + pathl + suffixl + 3));
00268     if (newfilename) 
00269     {
00270         if (*path != '/')
00271         {
00272             strcat(newfilename, prefix);
00273             if ((prefixl != 0) && (prefix[prefixl-1] != '/'))
00274             {
00275                 strcat(newfilename, "/");
00276             }
00277         }
00278         strcat(newfilename, path);
00279         if ((pathl  != 0) &&
00280             (suffixl != 0) && 
00281             (path[pathl-1] != '/') && 
00282              suffix[0] != '/')
00283         {
00284             strcat(newfilename, "/");
00285         }
00286         strcat(newfilename, suffix);
00287     }
00288     return newfilename;
00289 }
00290 
00291 /******************************************************************************
00292 Function:       fexist()
00293 Description:    check the existence of file corresponding to <path>
00294 Parameters:     path
00295 Returns:        1, if file exists
00296 ******************************************************************************/
00306 static int fexist(
00307         char * path
00308 )
00309 {
00310   struct stat sbuf;
00311   int res;
00312   
00313   if(!path || !*path) return 0;
00314 
00315   res=stat(path,&sbuf);
00316   if (res)
00317   {
00318       if (errno==ENOENT)
00319       {
00320           return 0;
00321       }
00322       else
00323       {
00324           return -1;
00325       }
00326   }
00327   return 1;
00328 }
00329 
00330 /******************************************************************************
00331 Function:       lcmaps_getfexist()
00332 Description:    picks the first existing file in argument list
00333 Parameters:     n   : number of paths,
00334                 ... : list of paths
00335 Returns:        returns filename found or NULL
00336 ******************************************************************************/
00349 char * lcmaps_getfexist(
00350         int n,
00351         ...
00352 )
00353 {
00354   va_list pvar;
00355   int i;
00356   char *cfilenm=NULL;
00357 
00358   va_start(pvar, n);
00359 
00360   for(i=0;i<n;i++) {
00361     cfilenm=va_arg(pvar,char*);
00362     if(*cfilenm) if(fexist(cfilenm)) return cfilenm;
00363   }
00364   va_end(pvar);
00365   return NULL;
00366 }
00367 
00368 /******************************************************************************
00369 Function:       lcmaps_findfile()
00370 Description:    Checks for file in standard directories
00371 Parameters:     name
00372 Returns:        returns filename found (should be freeed) or NULL
00373 ******************************************************************************/
00391 char * lcmaps_findfile(
00392         char * name
00393 )
00394 {
00395     char * newname=NULL;
00396     char * tmpname=NULL;
00397     char * names[5]={NULL,NULL,NULL,NULL,NULL};
00398     int    i;
00399 
00400     names[0]=lcmaps_genfilename(NULL,name,NULL);
00401     names[1]=lcmaps_genfilename("modules",name,NULL);
00402     names[2]=lcmaps_genfilename(LCMAPS_ETC_HOME,name,NULL);
00403     names[3]=lcmaps_genfilename(LCMAPS_MOD_HOME,name,NULL);
00404     names[4]=lcmaps_genfilename(LCMAPS_LIB_HOME,name,NULL);
00405 
00406     tmpname=lcmaps_getfexist(5,names[0],
00407                       names[1],names[2],
00408                       names[3],names[4]);
00409     if (tmpname != NULL)
00410         newname=strdup(tmpname);
00411     else
00412         newname=NULL;
00413 
00414     for (i=0; i < 5; i++)
00415     {
00416         if (names[i] != NULL) free(names[i]);
00417     }
00418 
00419     return newname;
00420 }
00421 
00422 /******************************************************************************
00423 Function:   lcmaps_tokenize() (in modified form from globus_gatekeeper_utils.c)
00424 
00425 Description:
00426     Breakup the command in to args, pointing the args array
00427     at the tokens. Replace white space at the end of each
00428     token with a null. A token maybe in quotes. 
00429 
00430 Parameters:
00431     command: The command line to be parsed.
00432     args:    A pointer to an array of pointers to be filled it
00433     n:       Size of the array, on input, and set to size used on output. 
00434     sep:     string of seperating characters
00435 
00436 Returns:
00437     0 on success. 
00438     -1 on to malloc
00439     -2 on to many args
00440     -3 on quote not matched
00441 ******************************************************************************/
00464 int lcmaps_tokenize(
00465         const char * command, 
00466         char ** args,
00467         int * n,
00468         char * sep
00469     )
00470 {
00471     int maxargs;
00472     int i;
00473     const char * cp;
00474     const char * pp;
00475     const char * qp;
00476     char ** arg;
00477 
00478     arg = args;
00479 /*    i = *n - 1; */
00480     i = 0;
00481     maxargs = *n;
00482 
00483     cp = command;
00484     while (*cp)
00485     {
00486     /* skip leading sep characters */
00487         while (*cp && strchr(sep, *cp))
00488         {
00489             cp++;
00490         }
00491         pp = NULL;
00492         if (*cp == '\"')
00493         {
00494             cp++;
00495             pp = cp;
00496             if ((qp = strchr(cp,'\"')) == NULL)
00497             {
00498                 *n = i;
00499                 return -3;
00500             }
00501             cp = qp + 1;
00502         }
00503         else if (*cp)
00504         {
00505             pp = cp;
00506             if ((qp = strpbrk(cp,sep)) == NULL)
00507             {
00508                 qp = strchr(cp,'\0');
00509             }
00510             cp = qp;
00511         }
00512         else
00513         {
00514             continue;
00515         }
00516         if (pp)
00517         {
00518             /*
00519              * fill at most maxargs-1 arguments; let the last one point to NULL
00520              */
00521             i++;
00522             if (i >= maxargs)
00523             {
00524                 i--;
00525                 *n = i;
00526                 return(-2); /* too many args */
00527             }
00528             *arg = (char*)malloc((qp - pp) + 1);
00529             if (*arg == NULL)
00530             {
00531                 i--;
00532                 *n = i;
00533                 return -1;
00534             }
00535             memcpy(*arg,pp,qp - pp);
00536             *(*arg + (qp - pp)) = '\0';
00537             arg++;
00538         }
00539     }
00540     *arg = NULL;
00541     *n = i;
00542     return(0);
00543 }
00544 /******************************************************************************
00545 Function:   lcmaps_get_gidlist()
00546 
00547 Description:
00548     Finds the list of gids for user in the group file (/etc/group)
00549     Returns a list of gid_t which should be freed by calling program.
00550 
00551 Parameters:
00552     username:   the name of the user
00553     ngroups:    ptr to int which will be filled with the number of gids.
00554     group_list: ptr to an array of gid_t.
00555 
00556 Returns:
00557     0 on success. 
00558     -1 on realloc failure
00559     -2 on getgrent failure
00560     1 on failure
00561 ******************************************************************************/
00579 int lcmaps_get_gidlist(
00580         const char * username,
00581         int * ngroups,
00582         gid_t ** group_list
00583     )
00584 {
00585     struct group        * group_info = NULL;
00586     gid_t               * groups = NULL;
00587     gid_t               * newgroups = NULL;
00588     int                   i = 0;
00589 
00590     /* rewind the file pointer to the beginning of the /etc/group file */
00591     setgrent();
00592 
00593     lcmaps_log_debug(2,"\tlcmaps_get_gidlist(): looping through group file\n");
00594     *ngroups = 0;
00595     while ( ( group_info = getgrent() ) )
00596     {
00597         char ** pgr_mem = group_info->gr_mem;
00598         char *  gr_mem = NULL;
00599 
00600         lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): group %s\n", group_info->gr_name);
00601         while ( (gr_mem = *pgr_mem) )
00602         {
00603             lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): \tgroup member %s\n", gr_mem);
00604             if (strncmp(username, gr_mem, strlen(username))==0)
00605             {
00606                 lcmaps_log_debug(2,"\tlcmaps_get_gidlist(): \t\tfound group %s for %s\n",
00607                     group_info->gr_name, username);
00608                 (*ngroups)++;
00609                 newgroups = (gid_t *) realloc(groups, ((*ngroups) * sizeof(gid_t)));
00610                 if (newgroups == NULL)
00611                 {
00612                     lcmaps_log(0,"lcmaps_get_gidlist(): cannot realloc\n");
00613                     free(groups);
00614                     return -1;
00615                 }
00616                 groups=newgroups;
00617                 groups[(*ngroups)-1] = group_info->gr_gid;
00618             }
00619             ++pgr_mem;
00620         }
00621     }
00622     if (errno==ENOMEM)
00623     {
00624         lcmaps_log(0,"lcmaps_get_gidlist(): Cannot read the group file, %s\n", strerror(errno));
00625         free(groups);
00626         groups=NULL;
00627         /* Close the group file */
00628         endgrent();
00629         return -2;
00630     }
00631     *group_list=groups;
00632     lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): %d groups found for %s\n", *ngroups, username);
00633     for (i = 0; i < *ngroups; i++)
00634     {
00635         lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): group nr %d ==> gid_t %d\n", i+1, groups[i]);
00636     }
00637     /* Close the group file */
00638     endgrent();
00639     return 0;
00640 }
00641 /******************************************************************************
00642 CVS Information:
00643     $Source: /local/reps/lcgware/fabric_mgt/gridification/lcmaps/src/pluginmanager/lcmaps_utils.c,v $
00644     $Date: 2004/10/01 15:17:32 $
00645     $Revision: 1.7 $
00646     $Author: maart $
00647 ******************************************************************************/

Generated on Sat Oct 2 02:18:27 2004 for edg-lcmaps by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002