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

Generated at Thu Mar 4 17:39:03 2004 for edg-lcmaps by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001