~ubuntu-branches/ubuntu/trusty/globus-gss-assist/trusty

« back to all changes in this revision

Viewing changes to .pc/globus-gss-assist-doxygen.patch/gridmap.c

  • Committer: Package Import Robot
  • Author(s): Mattias Ellert
  • Date: 2012-04-29 07:03:12 UTC
  • mfrom: (1.2.5)
  • Revision ID: package-import@ubuntu.com-20120429070312-vxpkcewt8lat0mwu
Tags: 8.5-1
* Update to Globus Toolkit 5.2.1
* Drop patches globus-gss-assist-doxygen.patch, globus-gss-assist-deps.patch
  and globus-gss-assist-format.patch (fixed upstream)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 1999-2006 University of Chicago
3
 
 * 
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 * 
8
 
 * http://www.apache.org/licenses/LICENSE-2.0
9
 
 * 
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
18
 
/**
19
 
 * @file module.c
20
 
 * GSSAPI module activation code
21
 
 *
22
 
 * $RCSfile: gridmap.c,v $
23
 
 * $Revision: 1.30 $
24
 
 * $Date $
25
 
 */
26
 
#endif
27
 
 
28
 
#include "globus_i_gss_assist.h"
29
 
#include "globus_gsi_system_config.h"
30
 
#include "globus_gsi_cert_utils.h"
31
 
#include "globus_callout.h"
32
 
#include <stdio.h>
33
 
#include <string.h>
34
 
#include <ctype.h>
35
 
typedef struct _gridmap_line_s {
36
 
  char *dn;
37
 
  char **user_ids;
38
 
} globus_i_gss_assist_gridmap_line_t;
39
 
 
40
 
#define WHITESPACE_CHARS                " \t\n"
41
 
#define QUOTING_CHARS                   "\""
42
 
#define ESCAPING_CHARS                  "\\"
43
 
#define COMMENT_CHARS                   "#"
44
 
/* Characters seperating user ids in the gridmap file */
45
 
#define USERID_SEP_CHARS                ","
46
 
/*
47
 
 * Characters that terminate a user id in the gridmap file. This
48
 
 * is a combination of whitespace and seperators.
49
 
 */
50
 
#define USERID_TERMINATOR_CHARS         USERID_SEP_CHARS WHITESPACE_CHARS
51
 
 
52
 
#ifndef NUL
53
 
#define NUL                             '\0'
54
 
#endif
55
 
 
56
 
#define GLOBUS_GENERIC_MAPPING_TYPE     "globus_mapping"
57
 
#define GLOBUS_GENERIC_AUTHZ_TYPE       "globus_authorization"
58
 
 
59
 
/*
60
 
 * Number of user id slots to allocate at a time
61
 
 * Arbitraty value, but must be >= 2.
62
 
 */
63
 
#define USERID_CHUNK_SIZE               4
64
 
 
65
 
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
66
 
 
67
 
static 
68
 
globus_result_t
69
 
globus_i_gss_assist_gridmap_find_dn(
70
 
    const char * const                  dn,
71
 
    globus_i_gss_assist_gridmap_line_t **                   
72
 
                                        gline);
73
 
 
74
 
static 
75
 
globus_result_t
76
 
globus_i_gss_assist_gridmap_find_local_user(
77
 
    const char * const                  local_user,
78
 
    globus_i_gss_assist_gridmap_line_t **                   
79
 
                                        gline);
80
 
 
81
 
static 
82
 
globus_result_t
83
 
globus_i_gss_assist_gridmap_parse_line(
84
 
    char *                              line,
85
 
    globus_i_gss_assist_gridmap_line_t **                   
86
 
                                        gline);
87
 
 
88
 
static void 
89
 
globus_i_gss_assist_gridmap_line_free(
90
 
    globus_i_gss_assist_gridmap_line_t *                    
91
 
                                        line);
92
 
 
93
 
static
94
 
globus_result_t 
95
 
globus_i_gss_assist_gridmap_parse_globusid(
96
 
    const char *                        unparse,
97
 
    char **                             pparsed);
98
 
 
99
 
static int 
100
 
globus_i_gss_assist_xdigit_to_value(
101
 
    char                                xdigit);
102
 
 
103
 
static
104
 
globus_result_t
105
 
globus_l_gss_assist_gridmap_lookup(
106
 
    gss_ctx_id_t                        context,
107
 
    char *                              service,
108
 
    char *                              desired_identity,
109
 
    char *                              identity_buffer,
110
 
    unsigned int                        identity_buffer_length);
111
 
  
112
 
static
113
 
globus_result_t
114
 
globus_l_gss_assist_line_length(
115
 
    FILE *                              fp,
116
 
    size_t *                            len);
117
 
 
118
 
#endif
119
 
 
120
 
 
121
 
 
122
 
/******************************************************************************
123
 
                       Start of gridmapdir functions
124
 
 
125
 
 These all use the environment variable GRIDMAPDIR
126
 
  (a) if not set, then the gridmapdir functions are not used
127
 
  (b) the value it is set to defines the gridmap directory
128
 
      (eg export GRIDMAPDIR=/etc/grid-security/gridmapdir)
129
 
 
130
 
******************************************************************************/
131
 
 
132
 
#include <utime.h>
133
 
#include <errno.h>
134
 
#include <dirent.h>
135
 
#include <unistd.h>
136
 
#include <sys/stat.h>
137
 
#include <pwd.h>
138
 
#include <sys/types.h>
139
 
 
140
 
/******************************************************************************
141
 
Function:   gridmapdir_otherlink
142
 
Description:
143
 
        find another link in GRIDMAPDIR to the same inode as firstlink
144
 
        and change the modification time of firstlink to now (so that we
145
 
        always know when this pair was last used)
146
 
        
147
 
Parameters:
148
 
        firstlink, the filename of the link we already know
149
 
 
150
 
Returns:
151
 
        a pointer to the other link's filename (without path) or NULL if none
152
 
        found (this is malloc'd and will need freeing)
153
 
 
154
 
******************************************************************************/
155
 
static char 
156
 
*gridmapdir_otherlink(char *   firstlink)
157
 
{
158
 
     int            ret;
159
 
     char           *firstlinkpath, *otherlinkdup, *otherlinkpath,
160
 
                    *gridmapdir;
161
 
     struct dirent  *gridmapdirentry;
162
 
     DIR            *gridmapdirstream;
163
 
     struct stat    statbuf;
164
 
     ino_t          firstinode;
165
 
 
166
 
     gridmapdir = getenv("GRIDMAPDIR");
167
 
     if (gridmapdir == NULL) return NULL;
168
 
     
169
 
     firstlinkpath = malloc(strlen(gridmapdir) + 2 + strlen(firstlink));
170
 
     sprintf(firstlinkpath, "%s/%s", gridmapdir, firstlink);     
171
 
     ret = stat(firstlinkpath, &statbuf);
172
 
     free(firstlinkpath);   
173
 
     if (ret != 0) return NULL;
174
 
     if (statbuf.st_nlink != 2) return NULL;
175
 
     
176
 
     firstinode = statbuf.st_ino; /* save for comparisons */
177
 
          
178
 
     gridmapdirstream = opendir(gridmapdir);
179
 
 
180
 
     if (gridmapdirstream != NULL)
181
 
     {
182
 
         while ((gridmapdirentry = readdir(gridmapdirstream)) != NULL)
183
 
         {       
184
 
                 if (strcmp(gridmapdirentry->d_name, firstlink) == 0) continue;
185
 
           
186
 
                 otherlinkpath = malloc(strlen(gridmapdir) + 2 + 
187
 
                                        strlen(gridmapdirentry->d_name));
188
 
                 sprintf(otherlinkpath, "%s/%s", gridmapdir, 
189
 
                                            gridmapdirentry->d_name);
190
 
 
191
 
                 ret = stat(otherlinkpath, &statbuf);     
192
 
                 if ((ret == 0) && (statbuf.st_ino == firstinode))
193
 
                 {
194
 
                      utime(otherlinkpath, (struct utimbuf *) NULL);
195
 
                      free(otherlinkpath);
196
 
                      otherlinkdup = strdup(gridmapdirentry->d_name);
197
 
                      closedir(gridmapdirstream);     
198
 
                      return otherlinkdup;
199
 
                 }
200
 
                 else free(otherlinkpath);
201
 
         }
202
 
         
203
 
         closedir(gridmapdirstream);     
204
 
     }
205
 
 
206
 
     return NULL;
207
 
}
208
 
 
209
 
/******************************************************************************
210
 
Function:   gridmapdir_urlencode
211
 
Description:
212
 
        Convert string to URL encoded and return pointer to the encoded
213
 
        version, obtained through malloc. Calling routine must free
214
 
        this. Here "URL encoded" means anything other than an isalnum()
215
 
        goes to %HH where HH is its ascii value in hex; also A-Z => a-z 
216
 
        This name is suitable for filenames since no / or spaces.
217
 
 
218
 
Parameters:
219
 
        rawstring, the string to be converted
220
 
 
221
 
Returns:
222
 
        a pointer to the encoded string or NULL if the malloc failed
223
 
 
224
 
******************************************************************************/
225
 
static char 
226
 
*gridmapdir_urlencode(char * rawstring)
227
 
{
228
 
     int          encodedchar = 0, rawchar = 0;
229
 
     char *       encodedstring;
230
 
     
231
 
     encodedstring = (char *) malloc(3 * strlen(rawstring) + 1);
232
 
     
233
 
     if (encodedstring == NULL) return (char *) NULL;
234
 
 
235
 
     while (rawstring[rawchar] != '\0')
236
 
     {
237
 
           if (isalnum(rawstring[rawchar]))
238
 
           {
239
 
               encodedstring[encodedchar] = tolower(rawstring[rawchar]);
240
 
               ++rawchar;
241
 
               ++encodedchar;
242
 
           }
243
 
           else
244
 
           {
245
 
               sprintf(&encodedstring[encodedchar], "%%%02x", 
246
 
                                               rawstring[rawchar]);
247
 
               ++rawchar;
248
 
               encodedchar = encodedchar + 3;
249
 
           }        
250
 
     }
251
 
 
252
 
     encodedstring[encodedchar] = '\0';
253
 
     
254
 
     return encodedstring;
255
 
}
256
 
 
257
 
/******************************************************************************
258
 
Function:   gridmapdir_newlease
259
 
Description:
260
 
        Search for an unleased local username to give to the globus user
261
 
        corresponding to encodedfilename, and then lease it.
262
 
 
263
 
Parameters: 
264
 
        encodedfilename, URL-encoded globus client name and pathname of 
265
 
           the globus user who requested authentication 
266
 
        usernameprefix, the prefix of acceptable usernames (or "\0")
267
 
 
268
 
Returns:
269
 
        no return value
270
 
******************************************************************************/
271
 
 
272
 
void
273
 
gridmapdir_newlease(char *     encodedglobusidp,
274
 
                    char *     usernameprefix)
275
 
{
276
 
     int            ret;
277
 
     char           *userfilename, *encodedfilename, *gridmapdir;
278
 
     struct dirent  *gridmapdirentry;
279
 
     DIR            *gridmapdirstream;
280
 
     struct stat    statbuf;
281
 
     
282
 
     gridmapdir = getenv("GRIDMAPDIR");
283
 
     if (gridmapdir == NULL) return;
284
 
 
285
 
     encodedfilename = malloc(strlen(gridmapdir) + (size_t) 2 + 
286
 
                              strlen(encodedglobusidp));
287
 
     sprintf(encodedfilename, "%s/%s", gridmapdir, encodedglobusidp);
288
 
 
289
 
     gridmapdirstream = opendir(gridmapdir);
290
 
 
291
 
     while ((gridmapdirentry = readdir(gridmapdirstream)) != NULL)
292
 
     {
293
 
       /* we dont want any files that dont look like acceptable usernames */
294
 
       if ((*(gridmapdirentry->d_name) == '%') || 
295
 
           (strcmp(gridmapdirentry->d_name, "root") == 0))   continue;
296
 
       else if (*(gridmapdirentry->d_name) == '.')           continue;
297
 
       else if (index(gridmapdirentry->d_name, '~') != NULL) continue;
298
 
       else if (strncmp(gridmapdirentry->d_name, usernameprefix,
299
 
                        strlen(usernameprefix)) != 0)        continue;
300
 
 
301
 
       userfilename = malloc(strlen(gridmapdir) + (size_t) 2 + 
302
 
                             strlen(gridmapdirentry->d_name));
303
 
       sprintf(userfilename, "%s/%s", gridmapdir, gridmapdirentry->d_name);
304
 
       stat(userfilename, &statbuf);
305
 
       
306
 
       if (statbuf.st_nlink == 1) /* this one isnt leased yet */
307
 
       {   
308
 
           ret = link(userfilename, encodedfilename);
309
 
           free(userfilename);
310
 
           if (ret != 0) 
311
 
           {
312
 
               /* link failed: this is probably because a VERY lucky
313
 
                  other process has obtained a lease for encodedfilename 
314
 
                  while we were faffing around */
315
 
               closedir(gridmapdirstream);
316
 
               free(encodedfilename);
317
 
               return;
318
 
           }
319
 
     
320
 
           stat(encodedfilename, &statbuf);
321
 
           if (statbuf.st_nlink > 2) 
322
 
           {
323
 
              /* two globusIDs have grabbed the same username: back off */
324
 
              unlink(encodedfilename);
325
 
              continue;
326
 
           }
327
 
 
328
 
           closedir(gridmapdirstream);
329
 
           free(encodedfilename);
330
 
           return; /* link worked ok, so return */
331
 
       }
332
 
       else free(userfilename); /* already in use, try next one */
333
 
     }
334
 
     
335
 
     closedir(gridmapdirstream);
336
 
     free(encodedfilename);
337
 
     return; /* no unleased names left: give up */     
338
 
}
339
 
     
340
 
/******************************************************************************
341
 
Function:   gridmapdir_userid
342
 
Description:
343
 
        This is equivalent to globus_gss_assist_gridmap but for the dynamic
344
 
        user ids in the gridmapdir: maps a globusID to a local unix user id,
345
 
        either one already leased, or calls gridmapdir_newlease() to obtain 
346
 
        a new lease. This is called by globus_gss_assist_gridmap if the 
347
 
        local user id in the static gridmap file begins . (for a dynamic id)
348
 
 
349
 
Parameters: 
350
 
        globusidp, globus client name who requested authentication 
351
 
        usernameprefix, prefix of the local usernames which would 
352
 
               be acceptable (or "\0" )
353
 
        *userid returned userid name for local system. 
354
 
 
355
 
Returns:
356
 
       
357
 
        0 on success
358
 
        !=0 on failure
359
 
 
360
 
******************************************************************************/
361
 
 
362
 
static int
363
 
gridmapdir_userid(char *     globusidp,
364
 
                  char *     usernameprefix,
365
 
                  char **    useridp)
366
 
{
367
 
     char             *encodedglobusidp;
368
 
     
369
 
     if (getenv("GRIDMAPDIR") == NULL) return 1; /* GRIDMAPDIR defined? */
370
 
 
371
 
     if (globusidp[0] != '/') return 1; /* must be a proper subject DN */
372
 
     
373
 
     encodedglobusidp = gridmapdir_urlencode(globusidp);
374
 
 
375
 
     *useridp = gridmapdir_otherlink(encodedglobusidp);
376
 
 
377
 
     if (*useridp == NULL) /* maybe no lease yet */
378
 
     {
379
 
         gridmapdir_newlease(encodedglobusidp, usernameprefix); 
380
 
         /* try making a lease */
381
 
         
382
 
         *useridp = gridmapdir_otherlink(encodedglobusidp); 
383
 
         /* check if there is a now a lease - possibly made by someone else */
384
 
 
385
 
         if (*useridp == NULL) 
386
 
         {
387
 
             free(encodedglobusidp);
388
 
             return 1; /* still no good */
389
 
         }
390
 
     }
391
 
 
392
 
     free(encodedglobusidp);
393
 
     return 0;
394
 
}
395
 
 
396
 
/******************************************************************************
397
 
Function:   gridmapdir_globusid
398
 
Description:
399
 
        This is equivalent to globus_gss_assist_map_local_user but for the 
400
 
        dynamic user ids in the gridmapdir: search through leases to find
401
 
        which globusID corresponds to a local unix user id.
402
 
        This is called by globus_gss_assist_map_local_user 
403
 
 
404
 
Parameters: 
405
 
        globus client name who requested authentication 
406
 
        *userid returned userid name for local system. 
407
 
 
408
 
Returns:
409
 
       
410
 
        0 on success
411
 
        !=0 on failure
412
 
 
413
 
******************************************************************************/
414
 
 
415
 
static int
416
 
gridmapdir_globusid(char *     useridp,
417
 
                    char **    globusidp)
418
 
{
419
 
     int              encodedptr = 0, decodedptr = 0;
420
 
     char             *encodedglobusidp;
421
 
 
422
 
     if (useridp == NULL || globusidp == NULL)
423
 
     {
424
 
         return 1;
425
 
     }
426
 
     
427
 
     if (useridp[0] == '/') return 1; /* must not be a subject DN */
428
 
     
429
 
     encodedglobusidp = gridmapdir_otherlink(useridp);
430
 
 
431
 
     if (encodedglobusidp == NULL) return 1; /* not leased */
432
 
     
433
 
     *globusidp = malloc(strlen(encodedglobusidp));
434
 
     
435
 
     while (encodedglobusidp[encodedptr] != '\0')
436
 
     {
437
 
            if (encodedglobusidp[encodedptr] != '%')
438
 
            {
439
 
                (*globusidp)[decodedptr] = encodedglobusidp[encodedptr];
440
 
                ++encodedptr;
441
 
                ++decodedptr;
442
 
            }
443
 
            else /* must be a %HH encoded character */
444
 
            {
445
 
                /* even paranoids have enemies ... */
446
 
                if (encodedglobusidp[encodedptr+1] == '\0') break;
447
 
                if (encodedglobusidp[encodedptr+2] == '\0') break;
448
 
 
449
 
                (*globusidp)[decodedptr] = 
450
 
                   globus_i_gss_assist_xdigit_to_value(encodedglobusidp[encodedptr+1]) * 16 +
451
 
                   globus_i_gss_assist_xdigit_to_value(encodedglobusidp[encodedptr+2]);
452
 
 
453
 
                encodedptr = encodedptr + 3;
454
 
                ++decodedptr;
455
 
            }
456
 
     }
457
 
              
458
 
     free(encodedglobusidp);
459
 
     (*globusidp)[decodedptr] = '\0';
460
 
     return 0;
461
 
}
462
 
 
463
 
/******************************************************************************
464
 
Function:   gridmapdir_userok
465
 
Description:
466
 
        This is equivalent to globus_gss_assist_userok but for the dynamic
467
 
        user ids in the gridmapdir: finds the local unix username leased to 
468
 
        a globusID and compare with the username being checked.
469
 
        This is called by globus_gss_assist_userok if the local user id in
470
 
        the static gridmap file is -  (for a dynamic id)
471
 
 
472
 
Parameters: 
473
 
        globus client name who requested authentication 
474
 
        userid to be checked
475
 
 
476
 
Returns:
477
 
        0 on success (authorization allowed)
478
 
        !=0 on failure or authorization denied
479
 
                
480
 
******************************************************************************/
481
 
 
482
 
static int
483
 
gridmapdir_userok(char *     globusidp,
484
 
                  char *     userid)
485
 
{
486
 
     char                    *encodedglobusidp, *leasedname;
487
 
     
488
 
     if (globusidp[0] != '/') return 1; /* must be a proper subject DN */
489
 
     
490
 
     encodedglobusidp = gridmapdir_urlencode(globusidp);
491
 
     leasedname       = gridmapdir_otherlink(encodedglobusidp);
492
 
     free(encodedglobusidp);
493
 
 
494
 
     if (leasedname == NULL) return 1;
495
 
 
496
 
     if (strcmp(userid, leasedname) == 0)
497
 
     {
498
 
         free(leasedname);
499
 
         return 0;
500
 
     }
501
 
     else
502
 
     {
503
 
         free(leasedname);
504
 
         return 1;
505
 
     }
506
 
}
507
 
 
508
 
/******************************************************************************
509
 
                     End of gridmapdir functions
510
 
******************************************************************************/
511
 
 
512
 
/**
513
 
 * @brief Look up the default mapping for a Grid identity in a gridmap file
514
 
 * @ingroup globus_gsi_gss_assist
515
 
 * 
516
 
 * @details
517
 
 * The globus_gss_assist_gridmap() function parses the default gridmap file
518
 
 * and modifies its @a useridp parameter to point to a copy of the string
519
 
 * containing the default local identity that the grid identity is mapped to.
520
 
 * If successful, the caller is responsible for freeing the string pointed
521
 
 * to by @a useridp.
522
 
 *
523
 
 * By default, @a globus_gss_assist_gridmap() looks for the default gridmap
524
 
 * file defined by the value of the GRIDMAP environment variable. If that
525
 
 * is not set, it falls back to $HOME/.gridmap.
526
 
 *
527
 
 * @param globusidp
528
 
 *     The GSSAPI name string of the identity who requested authorization
529
 
 * @param useridp
530
 
 *     A pointer to a string to be set to the default user ID for the local
531
 
 *     system. No validation is done to check that such a user exists.
532
 
 *
533
 
 * @return 
534
 
 *     On success, globus_gss_assist_gridmap() returns 0 and modifies the
535
 
 *     the string pointed to by the @a useridp parameter. If an error occurs,
536
 
 *     a non-zero value is returned and the value pointed to by @a useridp
537
 
 *     is undefined.
538
 
 *
539
 
 * @retval GLOBUS_SUCCESS
540
 
 *     Success
541
 
 * @retval 1
542
 
 *     Error
543
 
 */
544
 
int 
545
 
globus_gss_assist_gridmap(
546
 
    char *                              globusidp,
547
 
    char **                             useridp) 
548
 
{
549
 
    globus_result_t                     result = GLOBUS_SUCCESS;
550
 
    globus_i_gss_assist_gridmap_line_t *
551
 
                                        gline = NULL;
552
 
    char                               *usernameprefix;
553
 
    int                                 ret;
554
 
 
555
 
    static char *                       _function_name_ =
556
 
    "globus_gss_assist_gridmap";
557
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
558
 
 
559
 
    /* Check arguments */
560
 
    if ((globusidp == NULL) || (useridp == NULL))
561
 
    {
562
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
563
 
            result,
564
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
565
 
            (_GASL("Params passed to function are NULL")));
566
 
        goto exit;
567
 
    }
568
 
 
569
 
    *useridp = NULL;
570
 
 
571
 
    result = globus_i_gss_assist_gridmap_find_dn(globusidp, &gline);
572
 
    if(result != GLOBUS_SUCCESS)
573
 
    {
574
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
575
 
            result,
576
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
577
 
        goto exit;
578
 
    }
579
 
 
580
 
    if (gline != NULL)
581
 
    {
582
 
        if ((gline->user_ids == NULL) ||
583
 
            (gline->user_ids[0] == NULL))
584
 
        {
585
 
            /*
586
 
             * If we get here then something in this code is broken
587
 
             * or the gridmap file is badly formatted or, most likely,
588
 
             * both.
589
 
             */
590
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
591
 
                result,
592
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
593
 
                (_GASL("Invalid (NULL) user id values")));
594
 
            globus_i_gss_assist_gridmap_line_free(gline);
595
 
            goto exit;
596
 
        }
597
 
 
598
 
        /* First user id is default */
599
 
        *useridp = strdup(gline->user_ids[0]);
600
 
 
601
 
        globus_i_gss_assist_gridmap_line_free(gline);
602
 
 
603
 
        if (*useridp == NULL)
604
 
        {
605
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
606
 
                result,
607
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
608
 
                (_GASL("Duplicate string operation failed")));
609
 
            goto exit;
610
 
        }
611
 
 
612
 
        if ((*useridp)[0] == '.') /* need to use gridmapdir */
613
 
        {             
614
 
            usernameprefix = strdup(&((*useridp)[1]));
615
 
            free(*useridp); *useridp = NULL;
616
 
            ret = gridmapdir_userid(globusidp, usernameprefix, useridp);
617
 
            free(usernameprefix);
618
 
            return ret;
619
 
        }
620
 
 
621
 
    }
622
 
    else
623
 
    {
624
 
        char *                          gridmap_filename = NULL;
625
 
 
626
 
        GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
627
 
 
628
 
        /* No entry found in gridmap file for this user */
629
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
630
 
            result,
631
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
632
 
            (_GASL("The DN: %s could not be mapped to a valid user in the "
633
 
             "gridmap file: %s."),
634
 
             globusidp,
635
 
             gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
636
 
 
637
 
        free(gridmap_filename);
638
 
        goto exit;
639
 
    }
640
 
 
641
 
 exit:
642
 
 
643
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
644
 
    if(result == GLOBUS_SUCCESS)
645
 
    {
646
 
        return 0;
647
 
    }
648
 
    else
649
 
    {
650
 
        globus_object_t *               error_obj;
651
 
        error_obj = globus_error_get(result);
652
 
        globus_object_free(error_obj);
653
 
 
654
 
        return 1;
655
 
    }
656
 
}
657
 
/* globus_gss_assist_gridmap() */
658
 
 
659
 
/**
660
 
 * @brief Gridmap entry existence check
661
 
 * @ingroup globus_gsi_gss_assist
662
 
 *
663
 
 * @details
664
 
 * The @a globus_gss_assist_userok() function parses the default gridmap file
665
 
 * and checks whether any mapping exists for the grid identity passed as the
666
 
 * @a globusid parameter and the local user identity passed as the @ userid
667
 
 * parameter.
668
 
 *
669
 
 * By default, @a globus_gss_assist_userok() looks for the default gridmap
670
 
 * file defined by the value of the GRIDMAP environment variable. If that
671
 
 * is not set, it falls back to $HOME/.gridmap.
672
 
 *
673
 
 * @param globusid
674
 
 *     The GSSAPI name string of the identity who requested authorization
675
 
 * @param userid
676
 
 *     The local account name that access is sought for.
677
 
 *
678
 
 * @return
679
 
 *     If @a globus_gss_assist_userok() is able to find a mapping between
680
 
 *     @a globusid and @a userid, it returns 0; otherwise it returns 1.
681
 
 *
682
 
 * @retval GLOBUS_SUCCESS
683
 
 *     Success
684
 
 * @retval 1
685
 
 *     Error
686
 
 */
687
 
int
688
 
globus_gss_assist_userok(
689
 
    char *                              globusid,
690
 
    char *                              userid)
691
 
{
692
 
    char *                              gridmap_filename = NULL;
693
 
    globus_result_t                     result = GLOBUS_SUCCESS;
694
 
    globus_i_gss_assist_gridmap_line_t *                        
695
 
                                        gline = NULL;
696
 
    char **                             useridp;
697
 
    static char *                       _function_name_ =
698
 
        "globus_gss_assist_userok";
699
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
700
 
 
701
 
    /* Check arguments */
702
 
    if ((globusid == NULL) ||
703
 
        (userid == NULL))
704
 
    {
705
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
706
 
            result,
707
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
708
 
            (_GASL("Arguments passed to function are NULL")));
709
 
        goto exit;
710
 
    }
711
 
    
712
 
    result = globus_i_gss_assist_gridmap_find_dn(globusid, &gline);
713
 
    if(result != GLOBUS_SUCCESS)
714
 
    {
715
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
716
 
            result,
717
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
718
 
        goto exit;
719
 
    }
720
 
 
721
 
    if (gline == NULL)
722
 
    {
723
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
724
 
            result,
725
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
726
 
            (_GASL("The DN: %s does not map to the username: %s"),
727
 
             globusid,
728
 
             userid));
729
 
        goto exit;
730
 
    }
731
 
    if (gline->user_ids == NULL)
732
 
    {
733
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
734
 
            result,
735
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
736
 
            (_GASL("The gridmap is malformated.  No user id's could be be found.")));
737
 
        goto exit;
738
 
    }
739
 
 
740
 
    if (*((gline->user_ids)[0]) == '.') /* try using gridmapdir */ 
741
 
    {
742
 
        globus_i_gss_assist_gridmap_line_free(gline);
743
 
        return gridmapdir_userok(globusid, userid);
744
 
    }
745
 
    else
746
 
    for (useridp = gline->user_ids; *useridp != NULL; useridp++)
747
 
    {
748
 
        if (strcmp(*useridp, userid) == 0)
749
 
        {
750
 
            goto exit;
751
 
        }
752
 
    }
753
 
 
754
 
    GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
755
 
    GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
756
 
        result,
757
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_USER_ID_DOESNT_MATCH,
758
 
        (_GASL("The user id: %s, doesn't match the the DN: %s, in the "
759
 
         "gridmap file: %s"),
760
 
         globusid,
761
 
         userid,
762
 
         gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
763
 
    free(gridmap_filename);
764
 
 
765
 
 exit:
766
 
 
767
 
    if(gline)
768
 
    {
769
 
        globus_i_gss_assist_gridmap_line_free(gline);
770
 
    }
771
 
 
772
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
773
 
    if(result == GLOBUS_SUCCESS)
774
 
    {
775
 
        return 0;
776
 
    }
777
 
    else
778
 
    {
779
 
        globus_object_t *               error_obj;
780
 
        error_obj = globus_error_get(result);
781
 
        globus_object_free(error_obj);
782
 
 
783
 
        return 1;
784
 
    }
785
 
}
786
 
/* globus_gss_assist_userok() */
787
 
 
788
 
/**
789
 
 * @brief Look up the default Grid identity associated with a local user name
790
 
 * @ingroup globus_gsi_gss_assist
791
 
 *
792
 
 * @details
793
 
 * The @a globus_gss_assist_map_local_user() function parses the 
794
 
 * gridmap file to determine a if the user name passed as the @a local_user 
795
 
 * parameter is the default local user for a Grid ID in the gridmap file. If
796
 
 * so, it modifies @a globusidp to point to a copy of that ID. Otherwise, it
797
 
 * searches the gridmap file for a Grid ID that has a non-default mapping for
798
 
 * @a local_user and modifies @a globusidp to point to a copy of that ID.
799
 
 * If successful, the caller is responsible for freeing the string pointed to
800
 
 * by the @a globusidp pointer.
801
 
 *
802
 
 * By default, @a globus_gss_assist_map_local_user() looks for the default
803
 
 * gridmap file defined by the value of the GRIDMAP environment variable. If
804
 
 * that is not set, it falls back to $HOME/.gridmap.
805
 
 *
806
 
 * @param local_user
807
 
 *     The local username to find a Grid ID for
808
 
 * @param globusidp
809
 
 *     A Grid ID that maps from the local_user.
810
 
 *
811
 
 * @return
812
 
 *     On success, @a globus_gss_assist_map_local_user() returns 0 and
813
 
 *     modifies @a globusidp to point to a Grid ID that maps to @a local_user;
814
 
 *     otherwise, @a globus_gss_assist_map_local_user() returns 1 and the
815
 
 *     value pointed to by @a globusidp is undefined.
816
 
 *
817
 
 * @retval GLOBUS_SUCCESS
818
 
 *     Success
819
 
 * @retval 1
820
 
 *     Error
821
 
 */
822
 
int 
823
 
globus_gss_assist_map_local_user(
824
 
    char *                              local_user,
825
 
    char **                             globusidp) 
826
 
{
827
 
    char *                              gridmap_filename = NULL;
828
 
    globus_result_t                     result = GLOBUS_SUCCESS;
829
 
    globus_i_gss_assist_gridmap_line_t *                        
830
 
                                        gline = NULL;
831
 
    static char *                       _function_name_ =
832
 
        "globus_gss_assist_map_local_user";
833
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
834
 
 
835
 
    /* Check arguments */
836
 
    if ((local_user == NULL) ||
837
 
        (globusidp == NULL))
838
 
    {
839
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
840
 
            result,
841
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
842
 
            (_GASL("Arguments passed to the function are NULL.")));
843
 
        goto exit;
844
 
    }
845
 
 
846
 
    *globusidp = NULL;
847
 
 
848
 
    result = globus_i_gss_assist_gridmap_find_local_user(local_user, &gline);
849
 
    if(result != GLOBUS_SUCCESS)
850
 
    {
851
 
        /*
852
 
         * We failed to open the gridmap file.
853
 
         */
854
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
855
 
            result,
856
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
857
 
        goto exit;
858
 
    }
859
 
 
860
 
    if (gline != NULL)
861
 
    {
862
 
        if (gline->dn == NULL)
863
 
        {
864
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
865
 
                result,
866
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
867
 
                (_GASL("The gridmap file: %s is formatted incorrectly.  No "
868
 
                 "distinguished names could be found.")));
869
 
            goto exit;
870
 
        }
871
 
 
872
 
        /* First user id is default */
873
 
        *globusidp = strdup(gline->dn);
874
 
 
875
 
        if (*globusidp == NULL)
876
 
        {
877
 
            /* strdup() failed */
878
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
879
 
                result,
880
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
881
 
                (_GASL("The string duplication operation failed.")));
882
 
            goto exit;
883
 
        }
884
 
    }
885
 
    else
886
 
    {
887
 
        GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
888
 
        /* No entry found in gridmap file for this user */
889
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
890
 
            result,
891
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
892
 
            (_GASL("No DN entry found for user: %s in gridmap file: %s"),
893
 
             local_user,
894
 
             gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
895
 
        free(gridmap_filename);
896
 
        goto exit;
897
 
    }
898
 
 
899
 
 exit:
900
 
 
901
 
    if(gline)
902
 
    {
903
 
        globus_i_gss_assist_gridmap_line_free(gline);
904
 
    }
905
 
 
906
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
907
 
    if(result == GLOBUS_SUCCESS)
908
 
    {
909
 
        return 0;
910
 
    }
911
 
    else
912
 
    {
913
 
        globus_object_t *               error_obj;
914
 
        error_obj = globus_error_get(result);
915
 
        globus_object_free(error_obj);
916
 
 
917
 
        /* try with gridmapdir before giving up completely */
918
 
        return gridmapdir_globusid(local_user, globusidp);
919
 
    }
920
 
921
 
/* globus_gss_assist_map_local_user() */
922
 
 
923
 
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
924
 
 
925
 
/**
926
 
 * @name Gridmap Find DN
927
 
 */
928
 
/* @{ */
929
 
/**
930
 
 * @ingroup globus_i_gsi_gss_assist
931
 
 * Locate the entry for the given DN in the default gridmap file
932
 
 *
933
 
 * @param dn
934
 
 *        the distinguished name to search for
935
 
 * @param gline
936
 
 *        gives the line information 
937
 
 *
938
 
 * @return
939
 
 *        0 on success, otherwise an error object identifier is returned.
940
 
 *        use globus_error_get to get the error object from the id.  The
941
 
 *        resulting error object must be freed using globus_object_free
942
 
 *        when it is no longer needed.
943
 
 *
944
 
 * @see globus_error_get
945
 
 * @see globus_object_free
946
 
 */
947
 
static
948
 
globus_result_t
949
 
globus_i_gss_assist_gridmap_find_dn(
950
 
    const char * const                  dn,
951
 
    globus_i_gss_assist_gridmap_line_t **                       
952
 
                                        gline)
953
 
{
954
 
    char *                              gridmap_filename = NULL;
955
 
    globus_result_t                     result = GLOBUS_SUCCESS;
956
 
    char *                              open_mode = "r";
957
 
    FILE *                              gmap_stream = NULL;
958
 
    int                                 found = 0;
959
 
    globus_i_gss_assist_gridmap_line_t *                        
960
 
                                        gline_tmp = NULL;
961
 
    static char *                       _function_name_ =
962
 
        "globus_i_gss_assist_gridmap_find_dn";
963
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
964
 
 
965
 
 
966
 
    /* Check arguments */
967
 
    if (dn == NULL)
968
 
    {
969
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
970
 
            result,
971
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
972
 
            (_GASL("The DN passed to function is NULL.")));
973
 
        goto exit;
974
 
    }
975
 
 
976
 
    result = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
977
 
    if(result != GLOBUS_SUCCESS)
978
 
    {
979
 
        gridmap_filename = NULL;
980
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
981
 
            result,
982
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
983
 
        goto exit;
984
 
    }
985
 
 
986
 
    gmap_stream = fopen(gridmap_filename, open_mode);
987
 
 
988
 
    if (gmap_stream == NULL)
989
 
    {
990
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
991
 
            result,
992
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
993
 
            (_GASL("Couldn't open gridmap file: %s for reading."),
994
 
             gridmap_filename));
995
 
        goto exit;
996
 
    }
997
 
 
998
 
    free(gridmap_filename);
999
 
    gridmap_filename = NULL;
1000
 
 
1001
 
    do
1002
 
    {
1003
 
        size_t                          line_len;
1004
 
        char *                          line;
1005
 
 
1006
 
        result = globus_l_gss_assist_line_length(gmap_stream, &line_len);
1007
 
        if (result != GLOBUS_SUCCESS || line_len == 0)
1008
 
        {
1009
 
            break;
1010
 
        }
1011
 
 
1012
 
        line = malloc(++line_len);
1013
 
        if (line == NULL)
1014
 
        {
1015
 
            result = globus_error_put(globus_error_wrap_errno_error(
1016
 
                GLOBUS_GSI_GSS_ASSIST_MODULE,
1017
 
                errno,
1018
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1019
 
                __FILE__,
1020
 
                _function_name_,
1021
 
                __LINE__,
1022
 
                _GASL("Could not allocate enough memory")));
1023
 
            break;
1024
 
        }
1025
 
 
1026
 
        if (fgets(line, line_len, gmap_stream) == NULL)
1027
 
        {
1028
 
            free(line);
1029
 
            break;              /* EOF or error */
1030
 
        }
1031
 
 
1032
 
        result = globus_i_gss_assist_gridmap_parse_line(line, &gline_tmp);
1033
 
        if (result != GLOBUS_SUCCESS)
1034
 
        {
1035
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1036
 
                result,
1037
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1038
 
            free(line);
1039
 
            continue;           /* Parse error */
1040
 
        }
1041
 
 
1042
 
        if ((gline_tmp != NULL) &&
1043
 
            (globus_i_gsi_cert_utils_dn_cmp(dn, gline_tmp->dn) == 0))
1044
 
        {
1045
 
            found = 1;
1046
 
        }
1047
 
        else
1048
 
        {
1049
 
            globus_i_gss_assist_gridmap_line_free(gline_tmp);
1050
 
        }
1051
 
        free(line);
1052
 
    } while (!found);
1053
 
 
1054
 
    fclose(gmap_stream);
1055
 
    gmap_stream = NULL;
1056
 
 
1057
 
    if (found)
1058
 
    {
1059
 
        *gline = gline_tmp;
1060
 
    }
1061
 
    else
1062
 
    {
1063
 
        *gline = NULL;
1064
 
    }
1065
 
 
1066
 
 exit:
1067
 
 
1068
 
    if (gridmap_filename != NULL)
1069
 
    {
1070
 
        free(gridmap_filename);
1071
 
    }
1072
 
 
1073
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1074
 
    return result;
1075
 
1076
 
/* gridmap_find_dn() */
1077
 
/* @} */
1078
 
 
1079
 
/**
1080
 
 * @name Find Local User
1081
 
 */
1082
 
/* @{ */
1083
 
/**
1084
 
 * @ingroup globus_i_gsi_gss_assist
1085
 
 * Locate the first entry with the given local user as the default in the
1086
 
 * default gridmap file.  If the user is not a default on any entry, locate the
1087
 
 * first entry in which the user exists as a secondary mapping.
1088
 
 *
1089
 
 * @param local_user
1090
 
 *        the name to search for
1091
 
 * @param gline
1092
 
 *        the resulting gridmap_line_t contianing the user and DN information
1093
 
 *
1094
 
 * @return
1095
 
 *        0 on success, otherwise an error object identifier is returned.
1096
 
 *        use globus_error_get to get the error object from the id.  The
1097
 
 *        resulting error object must be freed using globus_object_free
1098
 
 *        when it is no longer needed.
1099
 
 *
1100
 
 * @see globus_error_get
1101
 
 * @see globus_object_free
1102
 
 */
1103
 
static
1104
 
globus_result_t
1105
 
globus_i_gss_assist_gridmap_find_local_user(
1106
 
    const char * const                  local_user,
1107
 
    globus_i_gss_assist_gridmap_line_t **                       
1108
 
                                        gline)
1109
 
{
1110
 
    char *                              gridmap_filename = NULL;
1111
 
    char *                              open_mode = "r";
1112
 
    FILE *                              gmap_stream = NULL;
1113
 
    int                                 found = 0;
1114
 
    globus_i_gss_assist_gridmap_line_t *                        
1115
 
                                        gline_tmp;
1116
 
    char **                             useridp;
1117
 
    char *                              nondefault_line = NULL;
1118
 
    globus_result_t                     result = GLOBUS_SUCCESS;
1119
 
    static char *                       _function_name_ =
1120
 
        "globus_i_gss_assist_gridmap_find_local_user";
1121
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1122
 
 
1123
 
    /* Check arguments */
1124
 
    if (local_user == NULL)
1125
 
    {
1126
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1127
 
            result,
1128
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
1129
 
            (_GASL("Arguments passed to function are NULL.")));
1130
 
        goto exit;
1131
 
    }
1132
 
 
1133
 
    result = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
1134
 
    if(result != GLOBUS_SUCCESS)
1135
 
    {
1136
 
        gridmap_filename = NULL;
1137
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1138
 
            result,
1139
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1140
 
        goto exit;
1141
 
    }
1142
 
            
1143
 
    gmap_stream = fopen(gridmap_filename, open_mode);
1144
 
 
1145
 
    if (gmap_stream == NULL)
1146
 
    {
1147
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1148
 
            result,
1149
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
1150
 
            (_GASL("Can't open the file: %s"), gridmap_filename));
1151
 
        goto exit;
1152
 
    }
1153
 
 
1154
 
    do
1155
 
    {
1156
 
        size_t                          line_len;
1157
 
        char *                          line;
1158
 
        char *                          save_line;
1159
 
 
1160
 
        result = globus_l_gss_assist_line_length(gmap_stream, &line_len);
1161
 
        if (result != GLOBUS_SUCCESS || line_len == 0)
1162
 
        {
1163
 
            break;
1164
 
        }
1165
 
        
1166
 
        line = malloc(++line_len);
1167
 
        if (line == NULL)
1168
 
        {
1169
 
            result = globus_error_put(globus_error_wrap_errno_error(
1170
 
                GLOBUS_GSI_GSS_ASSIST_MODULE,
1171
 
                errno,
1172
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1173
 
                __FILE__,
1174
 
                _function_name_,
1175
 
                __LINE__,
1176
 
                _GASL("Could not allocate enough memory")));
1177
 
            break;
1178
 
        }
1179
 
        
1180
 
        if (fgets(line, line_len, gmap_stream) == NULL)
1181
 
        {
1182
 
            free(line);
1183
 
            break;              /* EOF or error */
1184
 
        }
1185
 
 
1186
 
        save_line = strdup(line);
1187
 
        
1188
 
        result = globus_i_gss_assist_gridmap_parse_line(line, &gline_tmp);
1189
 
        if(result != GLOBUS_SUCCESS)
1190
 
        {
1191
 
            free(line);
1192
 
            free(save_line);
1193
 
            continue;           /* Parse error */
1194
 
        }
1195
 
 
1196
 
        if (gline_tmp == NULL)
1197
 
        {
1198
 
            /* Empty line */
1199
 
            free(line);
1200
 
            free(save_line);
1201
 
            continue;
1202
 
        }
1203
 
 
1204
 
        for(useridp = gline_tmp->user_ids; 
1205
 
            useridp != NULL && *useridp != NULL && !found; 
1206
 
            useridp++)
1207
 
        {
1208
 
            if(strcmp(local_user, *useridp) == 0)
1209
 
            {
1210
 
                /* check all names, but only stop looking if we match a 
1211
 
                 * default name.  save the first nondefault match til 
1212
 
                 * we've checked all the defaults */
1213
 
                if(*useridp == gline_tmp->user_ids[0])
1214
 
                {
1215
 
                    found = 1;
1216
 
                }
1217
 
                else if(nondefault_line == NULL)
1218
 
                {
1219
 
                    nondefault_line = strdup(save_line);
1220
 
                }
1221
 
            }
1222
 
        }
1223
 
        if(!found)
1224
 
        {
1225
 
            globus_i_gss_assist_gridmap_line_free(gline_tmp);
1226
 
        }
1227
 
        free(line);
1228
 
        free(save_line);
1229
 
    } while (!found);
1230
 
    
1231
 
    if(nondefault_line != NULL)
1232
 
    {
1233
 
        result = globus_i_gss_assist_gridmap_parse_line(
1234
 
            nondefault_line, &gline_tmp);
1235
 
        free(nondefault_line);
1236
 
        if(result != GLOBUS_SUCCESS)
1237
 
        {
1238
 
            goto exit;
1239
 
        }
1240
 
        found = 1;
1241
 
    }        
1242
 
 
1243
 
    fclose(gmap_stream);
1244
 
    gmap_stream = NULL;
1245
 
 
1246
 
    if (found)
1247
 
        *gline = gline_tmp;
1248
 
    else
1249
 
        *gline = NULL;
1250
 
 
1251
 
 exit:
1252
 
 
1253
 
    if (gridmap_filename)
1254
 
    {
1255
 
        free(gridmap_filename);
1256
 
    }
1257
 
 
1258
 
    if (gmap_stream)
1259
 
        fclose(gmap_stream);
1260
 
 
1261
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1262
 
    return result;
1263
 
}
1264
 
/* gridmap_find_local_user() */
1265
 
/* @} */
1266
 
 
1267
 
/**
1268
 
 * @name Gridmap Parse Line
1269
 
 */
1270
 
/* @{ */
1271
 
/**
1272
 
 * @ingroup globus_i_gsi_gss_assist
1273
 
 * 
1274
 
 * Given a line from the gridmap file, parse it returning
1275
 
 * a gridmap_line_t structure. line is modified during parsing.
1276
 
 * The format of the line is expected to be:
1277
 
 * <DN> <userid>[,<userid>[,<userid>...]]
1278
 
 * Leading and trailing whitespace is ignored.
1279
 
 * userids must only have a comma between them, no whitespace.
1280
 
 * Anything after the userids is ignored.
1281
 
 * Anything after an unescaped comment character is ignored.
1282
 
 *
1283
 
 * @param line
1284
 
 *        the line to parse
1285
 
 * @param gline
1286
 
 *        the resulting parsed gridmap line structure
1287
 
 *
1288
 
 * @return
1289
 
 *        0 on success, otherwise an error object identifier is returned.
1290
 
 *        use globus_error_get to get the error object from the id.  The
1291
 
 *        resulting error object must be freed using globus_object_free
1292
 
 *        when it is no longer needed.
1293
 
 *
1294
 
 * @see globus_error_get
1295
 
 * @see globus_object_free
1296
 
 */
1297
 
static
1298
 
globus_result_t
1299
 
globus_i_gss_assist_gridmap_parse_line(
1300
 
    char *                              line,
1301
 
    globus_i_gss_assist_gridmap_line_t **                       
1302
 
                                        gline)
1303
 
{
1304
 
    char *                              dn_end;
1305
 
    char *                              parsed_dn = NULL;
1306
 
    char **                             userids = NULL;
1307
 
    int                                 num_userids = 0;
1308
 
    int                                 userid_slots = 0;
1309
 
    globus_i_gss_assist_gridmap_line_t *                        
1310
 
                                        gline_tmp = NULL;
1311
 
    globus_result_t                     result = GLOBUS_SUCCESS;
1312
 
    static char *                       _function_name_ =
1313
 
        "globus_i_gss_assist_gridmap_parse_line";
1314
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1315
 
    
1316
 
    /* Check arguments */
1317
 
    if ((line == NULL) ||
1318
 
        (gline == NULL))
1319
 
    {
1320
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1321
 
            result,
1322
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
1323
 
            (_GASL("Arguments passed to function are NULL.")));
1324
 
        goto exit;
1325
 
    }
1326
 
 
1327
 
    /* Skip over leading whitespace */
1328
 
    line += strspn(line, WHITESPACE_CHARS);
1329
 
 
1330
 
    /* Check for comment at start of line and ignore line if present */
1331
 
    if (strchr(COMMENT_CHARS, *line) != NULL) 
1332
 
    {
1333
 
        /* Ignore line, return NULL gline */
1334
 
        *gline = NULL;
1335
 
        goto exit;
1336
 
    }
1337
 
        
1338
 
    /* Check for empty line */
1339
 
    if (*line == NUL)
1340
 
    {
1341
 
        /* Empty line, return NULL gline. */
1342
 
        *gline = NULL;
1343
 
        goto exit;
1344
 
    }
1345
 
 
1346
 
    /* Is DN quoted? */
1347
 
    if (strchr(QUOTING_CHARS, *line) != NULL)
1348
 
    {
1349
 
        /*
1350
 
         * Yes, skip over opening quote and look for unescaped
1351
 
         * closing double quote
1352
 
         */
1353
 
        line++;
1354
 
        dn_end = line;
1355
 
 
1356
 
        do
1357
 
        {
1358
 
            /* If loop below resolves bug 4979 */
1359
 
            if (strchr(ESCAPING_CHARS, *(dn_end - 1))) 
1360
 
            {
1361
 
                dn_end++;
1362
 
            }
1363
 
            
1364
 
            dn_end += strcspn(dn_end, QUOTING_CHARS);
1365
 
 
1366
 
            if (*dn_end == NUL)
1367
 
            {
1368
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1369
 
                    result,
1370
 
                    GLOBUS_GSI_GSS_ASSIST_ERROR_INVALID_GRIDMAP_FORMAT,
1371
 
                    (_GASL("A closing quote is missing in the gridmap file, "
1372
 
                     "on the line:\n%s\n"),
1373
 
                     line));
1374
 
                goto exit;
1375
 
            }
1376
 
 
1377
 
            /* Make sure it's not escaped */
1378
 
        }
1379
 
        while (strchr(ESCAPING_CHARS, *(dn_end - 1)) != NULL);
1380
 
    }
1381
 
    else
1382
 
    {
1383
 
        /* No, just find next whitespace */
1384
 
        dn_end = line + strcspn(line, WHITESPACE_CHARS);
1385
 
 
1386
 
        if (*dn_end == NUL)
1387
 
        {
1388
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1389
 
                result,
1390
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_INVALID_GRIDMAP_FORMAT,
1391
 
                (_GASL("Nothing follows the DN on the line:\n%s\n"),
1392
 
                 line));
1393
 
            goto exit;
1394
 
        }
1395
 
    }
1396
 
 
1397
 
    /* NUL terminate DN and parse */
1398
 
    *dn_end = NUL;
1399
 
 
1400
 
    result = globus_i_gss_assist_gridmap_parse_globusid(line, &parsed_dn);
1401
 
    if(result != GLOBUS_SUCCESS)
1402
 
    {
1403
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1404
 
            result,
1405
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1406
 
        goto exit;
1407
 
    }
1408
 
 
1409
 
    /* Skip over closing delim and any whitespace after DN */
1410
 
    line = dn_end + 1;
1411
 
    line += strspn(line, WHITESPACE_CHARS);
1412
 
 
1413
 
    /* Parse list of unix user ID seperated by USERID_SEP_CHARS */
1414
 
    while (*line != NUL)
1415
 
    {
1416
 
        int                                     userid_len;
1417
 
 
1418
 
        /* Find end of this userid */
1419
 
        userid_len = strcspn(line, USERID_TERMINATOR_CHARS);
1420
 
 
1421
 
        /* Make sure we have a slot and if not allocate it */
1422
 
        if ((num_userids + 1 /* new entry */+ 1 /* for NULL */) > userid_slots)
1423
 
        {
1424
 
            char **userids_tmp;
1425
 
            userid_slots += USERID_CHUNK_SIZE;
1426
 
            userids_tmp = realloc(userids, userid_slots * sizeof(char *));
1427
 
 
1428
 
            if (!userids_tmp)
1429
 
            {
1430
 
                result = globus_error_put(globus_error_wrap_errno_error(
1431
 
                    GLOBUS_GSI_GSS_ASSIST_MODULE,
1432
 
                    errno,
1433
 
                    GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1434
 
                    __FILE__,
1435
 
                    _function_name_,
1436
 
                    __LINE__,
1437
 
                    _GASL("Could not allocate enough memory")));
1438
 
                goto error_exit;
1439
 
            }
1440
 
 
1441
 
            userids = userids_tmp;
1442
 
        }
1443
 
  
1444
 
        userids[num_userids] = malloc(userid_len + 1 /* for NUL */);
1445
 
 
1446
 
        if (!userids[num_userids])
1447
 
        {
1448
 
            result = globus_error_put(globus_error_wrap_errno_error(
1449
 
                GLOBUS_GSI_GSS_ASSIST_MODULE,
1450
 
                errno,
1451
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1452
 
                __FILE__,
1453
 
                _function_name_,
1454
 
                __LINE__,
1455
 
                _GASL("Could not allocate enough memory")));
1456
 
            goto error_exit;
1457
 
        }
1458
 
 
1459
 
        strncpy(userids[num_userids], line, userid_len);
1460
 
        userids[num_userids][userid_len] = NUL;
1461
 
 
1462
 
        num_userids++;
1463
 
        userids[num_userids] = NULL;
1464
 
 
1465
 
        line += userid_len;
1466
 
        line += strspn(line, USERID_TERMINATOR_CHARS);
1467
 
    }
1468
 
 
1469
 
    /* Ok, build our gridmap_line_t structure */
1470
 
    gline_tmp = malloc(sizeof(*gline_tmp));
1471
 
 
1472
 
    if (gline_tmp == NULL)
1473
 
    {
1474
 
        result = globus_error_put(globus_error_wrap_errno_error(
1475
 
            GLOBUS_GSI_GSS_ASSIST_MODULE,
1476
 
            errno,
1477
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1478
 
            __FILE__,
1479
 
            _function_name_,
1480
 
            __LINE__,
1481
 
            _GASL("Could not allocate enough memory")));
1482
 
        goto error_exit;
1483
 
    }
1484
 
 
1485
 
    gline_tmp->dn = parsed_dn;
1486
 
    gline_tmp->user_ids = userids;
1487
 
 
1488
 
    *gline = gline_tmp;
1489
 
  
1490
 
    goto exit;
1491
 
 
1492
 
 error_exit:
1493
 
 
1494
 
    if (parsed_dn)
1495
 
    {
1496
 
        free(parsed_dn);
1497
 
    }
1498
 
 
1499
 
    if (userids)
1500
 
    {
1501
 
        char **userids_tmp = userids;
1502
 
 
1503
 
        while (*userids_tmp != NULL)
1504
 
        {
1505
 
            free(*userids_tmp++);
1506
 
        }
1507
 
 
1508
 
        free(userids);
1509
 
    }
1510
 
 
1511
 
 exit:
1512
 
 
1513
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1514
 
    return result;
1515
 
1516
 
/* gridmap_parse_line() */
1517
 
/* @} */
1518
 
 
1519
 
/**
1520
 
 * @name globus_i_gsi_gss_assist
1521
 
 */
1522
 
/* @{ */
1523
 
/**
1524
 
 * @ingroup globus_i_gsi_gss_assist
1525
 
 * Frees all memory allocated to a gridmap_line_t structure.
1526
 
 *
1527
 
 * @param gline
1528
 
 *        pointer to structure to be freed.
1529
 
 * 
1530
 
 * @return
1531
 
 *        void
1532
 
 */
1533
 
static
1534
 
void
1535
 
globus_i_gss_assist_gridmap_line_free(
1536
 
    globus_i_gss_assist_gridmap_line_t *                    
1537
 
                                        gline)
1538
 
{
1539
 
    static char *                       _function_name_ =
1540
 
        "globus_i_gss_assist_gridmap_line_free";
1541
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1542
 
 
1543
 
    if (gline != NULL)
1544
 
    {
1545
 
        if (gline->dn != NULL)
1546
 
        {
1547
 
            free(gline->dn);
1548
 
        }
1549
 
        
1550
 
        if (gline->user_ids != NULL)
1551
 
        {
1552
 
            char **                           userids_tmp = gline->user_ids;
1553
 
            
1554
 
            while (*userids_tmp != NULL)
1555
 
            {
1556
 
                free(*userids_tmp++);
1557
 
            }
1558
 
            
1559
 
            free(gline->user_ids);
1560
 
        }
1561
 
        
1562
 
        free(gline);
1563
 
    }
1564
 
1565
 
/* gridmap_free_gridmap_line() */
1566
 
/* @} */
1567
 
 
1568
 
/**
1569
 
 * @name Gridmap Parse Globusid
1570
 
 */
1571
 
/* @{ */
1572
 
/**
1573
 
 * @ingroup globus_i_gsi_gss_assist
1574
 
 * Given a pointer to a string containing the globusid from the
1575
 
 * gridmap file, return a pointer to a string containing the
1576
 
 * parsed from of the id.
1577
 
 *
1578
 
 * Specifically handle backslashed characters - e.g. '\\',
1579
 
 * '\x4a' or '\37'.
1580
 
 *
1581
 
 * @param unparsed
1582
 
 *        the unparsed globusid
1583
 
 * @param pparsed
1584
 
 *        the resulting parsed string - this should be freed when
1585
 
 *        no longer needed
1586
 
 * @result
1587
 
 *        0 on success, otherwise an error object identifier is returned.
1588
 
 *        use globus_error_get to get the error object from the id.  The
1589
 
 *        resulting error object must be freed using globus_object_free
1590
 
 *        when it is no longer needed.
1591
 
 *
1592
 
 * @see globus_error_get
1593
 
 * @see globus_object_free
1594
 
 */
1595
 
static
1596
 
globus_result_t
1597
 
globus_i_gss_assist_gridmap_parse_globusid(
1598
 
    const char *                        unparsed,
1599
 
    char **                             pparsed)
1600
 
{
1601
 
    /* Is the current character escaped? (Previous char was backslash) */
1602
 
    int                                 escaped = 0;
1603
 
 
1604
 
  /* Buffer we are putting resulting name into */
1605
 
    char *                              buffer = NULL;
1606
 
 
1607
 
    /* Buffer's length in bytes */
1608
 
    int                                 buffer_len = 0;
1609
 
 
1610
 
    /* And our current position in buffer */
1611
 
    int                                 buffer_index = 0;
1612
 
 
1613
 
    /* Character we're currently looking at */
1614
 
    char                                unparsed_char;
1615
 
 
1616
 
    globus_result_t                     result = GLOBUS_SUCCESS;
1617
 
    static char *                       _function_name_ =
1618
 
        "globus_i_gss_assist_gridmap_parse_globusid";
1619
 
 
1620
 
    static char *                       hexdigit = "0123456789ABCDEF";
1621
 
 
1622
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1623
 
 
1624
 
    /*
1625
 
     * Check input parameters for legality
1626
 
     */
1627
 
    if ((unparsed == NULL) ||
1628
 
        (pparsed == NULL))
1629
 
    {
1630
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1631
 
            result,
1632
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
1633
 
            (_GASL("Arguments passed to function are NULL.")));
1634
 
        goto exit;
1635
 
    }
1636
 
 
1637
 
    buffer_len = strlen(unparsed);
1638
 
    buffer = malloc(buffer_len);
1639
 
 
1640
 
    if (buffer == NULL)
1641
 
    {
1642
 
        globus_error_put(globus_error_wrap_errno_error( 
1643
 
            GLOBUS_GSI_GSS_ASSIST_MODULE, 
1644
 
            errno, 
1645
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO, 
1646
 
            __FILE__,
1647
 
            _function_name_,
1648
 
            __LINE__,
1649
 
            _GASL("Could not allocate enough memory")));
1650
 
        goto exit;
1651
 
    }
1652
 
 
1653
 
    /*
1654
 
     * Walk through the name, parsing as we go
1655
 
     */
1656
 
    while ((unparsed_char = *(unparsed++)) != NUL)
1657
 
    {
1658
 
        /* Unescaped backslash */
1659
 
        if (strchr(ESCAPING_CHARS, unparsed_char) && !escaped)
1660
 
        {
1661
 
            escaped = 1;
1662
 
            continue;
1663
 
        }
1664
 
 
1665
 
        /* Escaped hex character - e.g. '\xfe' */
1666
 
        if ((unparsed_char == 'x') && escaped)
1667
 
        {
1668
 
            if (isxdigit(*unparsed) &&
1669
 
                isxdigit(*(unparsed + 1)))
1670
 
            {
1671
 
                /* Set unparsed_char to value represented by hex value */
1672
 
                unparsed_char =
1673
 
                    (globus_i_gss_assist_xdigit_to_value(*unparsed) << 4) +
1674
 
                    globus_i_gss_assist_xdigit_to_value(*(unparsed + 1));
1675
 
        
1676
 
                unparsed += 2;
1677
 
            }
1678
 
            /* else just fall through */
1679
 
        }
1680
 
 
1681
 
        /*
1682
 
         * Ok, we now have the character in unparsed_char to be appended
1683
 
         * to our output string.
1684
 
         *
1685
 
         * First, make sure we have enough room in our output buffer.
1686
 
         */
1687
 
 
1688
 
        while ((buffer_index + 4) >= buffer_len)
1689
 
        {
1690
 
            /* Grow buffer */
1691
 
            char *tmp_buffer;
1692
 
 
1693
 
            buffer_len *= 2;
1694
 
 
1695
 
            tmp_buffer = realloc(buffer, buffer_len);
1696
 
 
1697
 
            if (tmp_buffer == NULL)
1698
 
            {
1699
 
                free(buffer);
1700
 
                globus_error_put(globus_error_wrap_errno_error(
1701
 
                    GLOBUS_GSI_GSS_ASSIST_MODULE,
1702
 
                    errno,
1703
 
                    GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1704
 
                    __FILE__,
1705
 
                    _function_name_,
1706
 
                    __LINE__,
1707
 
                    _GASL("Could not allocate enough memory")));
1708
 
                goto exit;
1709
 
            }
1710
 
            
1711
 
            buffer = tmp_buffer;
1712
 
        }
1713
 
 
1714
 
        if ((unparsed_char < ' ') || (unparsed_char > '~'))
1715
 
        {
1716
 
            buffer[buffer_index++] = '\\';
1717
 
            buffer[buffer_index++] = 'x';
1718
 
            buffer[buffer_index++] = hexdigit[(unparsed_char >> 4) & 0x0f];
1719
 
            buffer[buffer_index++] = hexdigit[unparsed_char & 0x0f];
1720
 
        }
1721
 
        else
1722
 
        {
1723
 
            buffer[buffer_index++] = unparsed_char;
1724
 
        }
1725
 
        buffer[buffer_index] = NUL;
1726
 
 
1727
 
        escaped = 0;
1728
 
    }
1729
 
    
1730
 
    /* XXX What if escaped == 1 here? */
1731
 
    /* Success */
1732
 
    
1733
 
    *pparsed = buffer;
1734
 
    
1735
 
 exit:
1736
 
    
1737
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1738
 
    return result;
1739
 
1740
 
/* gridmap_parse_globusid() */
1741
 
/* @} */
1742
 
 
1743
 
/**
1744
 
 * @name Hexadecimal Digit to Integer
1745
 
 */
1746
 
/* @{ */
1747
 
/**
1748
 
 * @ingroup globus_i_gsi_gss_assist
1749
 
 * Convert an ascii character representing a hexadecimal digit
1750
 
 * into an integer.
1751
 
 *
1752
 
 * @param xdigit
1753
 
 *        character contianing the hexidecimal digit
1754
 
 *
1755
 
 * @return
1756
 
 *        the value in the xdigit, or -1 if error
1757
 
 */
1758
 
static int
1759
 
globus_i_gss_assist_xdigit_to_value(
1760
 
    char                                xdigit)
1761
 
{
1762
 
    if ((xdigit >= '0') && (xdigit <= '9'))
1763
 
        return (xdigit - '0');
1764
 
 
1765
 
    if ((xdigit >= 'a') && (xdigit <= 'f'))
1766
 
        return (xdigit - 'a' + 0xa);
1767
 
 
1768
 
    if ((xdigit >= 'A') && (xdigit <= 'F'))
1769
 
        return (xdigit - 'A' + 0xa);
1770
 
 
1771
 
    /* Illegal digit */
1772
 
    return -1;
1773
 
1774
 
/* xdigit_to_value() */
1775
 
/* @} */
1776
 
 
1777
 
#endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */
1778
 
 
1779
 
 
1780
 
/**
1781
 
 * @brief Look up all Grid IDs associated with a local user ID
1782
 
 * @ingroup globus_gsi_gss_assist
1783
 
 *
1784
 
 * @details
1785
 
 * The @a globus_gss_assist_lookup_all_globusid() function parses a 
1786
 
 * gridmap file and finds all Grid IDs that map to a local user ID.
1787
 
 * The @a dns parameter is modified to point to an array of Grid ID
1788
 
 * strings from the gridmap file, and the @a dn_count parameter is
1789
 
 * modified to point to the number of Grid ID strings in the array.
1790
 
 * The caller is responsible for freeing the array using the macro
1791
 
 * @a GlobusGssAssistFreeDNArray().
1792
 
 *
1793
 
 * By default, @a globus_gss_assist_lookup_all_globusid() looks for the default
1794
 
 * gridmap file defined by the value of the GRIDMAP environment variable. If
1795
 
 * that is not set, it falls back to $HOME/.gridmap.
1796
 
 *
1797
 
 * @param username
1798
 
 *     The local username to look up in the gridmap file.
1799
 
 * @param dns
1800
 
 *     A pointer to an array of strings. This function modifies this
1801
 
 *     to point to a newly allocated array of strings. The
1802
 
 *     caller must use the macro @a GlobusGssAssistFreeDNArray() to free
1803
 
 *     this memory.
1804
 
 * @param dn_count
1805
 
 *     A pointer to an integer that is modified to contain the number of 
1806
 
 *     entries in the array returned via the @a dns parameter.
1807
 
 *
1808
 
 * @return
1809
 
 *     On success, @a globus_gss_assist_lookup_all_globusid() returns
1810
 
 *     GLOBUS_SUCCESS and modifies its @a dns and @a dn_count parameters as
1811
 
 *     described above. If an error occurs,
1812
 
 *     @a globus_gss_assist_lookup_all_globusid() returns a globus_result_t
1813
 
 *     that can be resolved to an error object and the values
1814
 
 *     pointed to by @a dns and @a dn_count are undefined.
1815
 
 *
1816
 
 * @retval GLOBUS_SUCCESS
1817
 
 *     Success
1818
 
 * @retval GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS
1819
 
 *     Error with arguments
1820
 
 * @retval GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP
1821
 
 *     Invalid path to gridmap
1822
 
 * @retval GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO
1823
 
 *     System error
1824
 
 */
1825
 
globus_result_t
1826
 
globus_gss_assist_lookup_all_globusid(
1827
 
    char *                                      username,
1828
 
    char **                                     dns[],
1829
 
    int *                                       dn_count)
1830
 
{
1831
 
    char *                                      line;
1832
 
    size_t                                      line_len;
1833
 
    int                                         i;
1834
 
    int                                         max_ndx = 512;
1835
 
    int                                         ndx = 0;
1836
 
    char **                                     l_dns;
1837
 
    globus_i_gss_assist_gridmap_line_t *        gline = NULL;
1838
 
    char *                                      gridmap_filename = NULL;
1839
 
    globus_result_t                             res = GLOBUS_SUCCESS;
1840
 
    FILE *                                      gmap_stream = NULL;
1841
 
    static char *                       _function_name_ =
1842
 
        "globus_gss_assist_lookup_all_globusid";
1843
 
 
1844
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1845
 
 
1846
 
    /* Check arguments */
1847
 
    if(dns == NULL ||
1848
 
       username == NULL ||
1849
 
       dn_count == NULL)
1850
 
    {
1851
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1852
 
            res,
1853
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
1854
 
            (_GASL("An argument passed to function is NULL.")));
1855
 
 
1856
 
        goto exit;
1857
 
    }
1858
 
 
1859
 
    res = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
1860
 
    if(res != GLOBUS_SUCCESS)
1861
 
    {
1862
 
        gridmap_filename = NULL;
1863
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1864
 
            res,
1865
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1866
 
 
1867
 
        goto exit;
1868
 
    }
1869
 
 
1870
 
    gmap_stream = fopen(gridmap_filename, "r");
1871
 
 
1872
 
    if (gmap_stream == NULL)
1873
 
    {
1874
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1875
 
            res,
1876
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
1877
 
            (_GASL("Couldn't open gridmap file: %s for reading."),
1878
 
             gridmap_filename));
1879
 
 
1880
 
        goto exit;
1881
 
    }
1882
 
 
1883
 
    ndx = 0;
1884
 
    l_dns = (char **)globus_malloc(sizeof(char *) * max_ndx);
1885
 
 
1886
 
    while (!feof(gmap_stream))
1887
 
    {
1888
 
        res = globus_l_gss_assist_line_length(gmap_stream, &line_len);
1889
 
        if (res != GLOBUS_SUCCESS || line_len == 0)
1890
 
        {
1891
 
            break;
1892
 
        }
1893
 
 
1894
 
        line = malloc(++line_len);
1895
 
        if (line == NULL)
1896
 
        {
1897
 
            res = globus_error_put(globus_error_wrap_errno_error(
1898
 
                GLOBUS_GSI_GSS_ASSIST_MODULE,
1899
 
                errno,
1900
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1901
 
                __FILE__,
1902
 
                _function_name_,
1903
 
                __LINE__,
1904
 
                _GASL("Could not allocate enough memory")));
1905
 
            break;
1906
 
        }
1907
 
 
1908
 
        if (fgets(line, line_len, gmap_stream) == NULL)
1909
 
        {
1910
 
            free(line);
1911
 
            break;
1912
 
        }
1913
 
 
1914
 
        res = globus_i_gss_assist_gridmap_parse_line(line, &gline);
1915
 
 
1916
 
        if(res == GLOBUS_SUCCESS &&
1917
 
           gline != NULL &&
1918
 
           gline->user_ids != NULL)
1919
 
        {
1920
 
            for (i = 0; gline->user_ids[i] != NULL; i++)
1921
 
            {
1922
 
                if(strcmp(gline->user_ids[i], username) == 0)
1923
 
                {
1924
 
                    l_dns[ndx] = strdup(gline->dn);
1925
 
                    ndx++;
1926
 
                    if(ndx >= max_ndx)
1927
 
                    {
1928
 
                        max_ndx *= 2;
1929
 
                        l_dns = (char **)globus_libc_realloc(l_dns,
1930
 
                                             sizeof(char *) * max_ndx);
1931
 
                    }
1932
 
                    break;
1933
 
                }
1934
 
            }
1935
 
        }
1936
 
        if (gline != NULL)
1937
 
        {
1938
 
            globus_i_gss_assist_gridmap_line_free(gline);
1939
 
            gline = NULL;
1940
 
        }
1941
 
        free(line);
1942
 
    }
1943
 
    l_dns[ndx] = NULL;
1944
 
    *dns = l_dns;
1945
 
    *dn_count = ndx;
1946
 
 
1947
 
    fclose(gmap_stream);
1948
 
    gmap_stream = NULL;
1949
 
 
1950
 
 exit:
1951
 
 
1952
 
    if(gridmap_filename != NULL)
1953
 
    {
1954
 
        free(gridmap_filename);
1955
 
    }
1956
 
 
1957
 
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1958
 
 
1959
 
    return res;
1960
 
}
1961
 
/* globus_gss_assist_lookup_all_globusid() */
1962
 
 
1963
 
 
1964
 
/**
1965
 
 * @brief Authorize the peer of a security context to use a service
1966
 
 * @ingroup globus_gsi_gss_assist
1967
 
 *
1968
 
 * @details
1969
 
 * The globus_gss_assist_map_and_authorize() function attempts to authorize
1970
 
 * the peer of a security context to use a particular service. If
1971
 
 * the @a desired_identity parameter is non-NULL, the authorization will
1972
 
 * succeed only if the peer is authorized for that identity. Otherwise,
1973
 
 * any valid authorized local user name will be used. If authorized, the
1974
 
 * local user name will be copied to the string pointed to by the
1975
 
 * @a identity_buffer parameter, which must be at least as long as the
1976
 
 * value passed as the @a identity_buffer_length parameter.
1977
 
 *
1978
 
 * If authorization callouts are defined in the callout configuration
1979
 
 * file, @a globus_gss_assist_map_and_authorize() will invoke both the
1980
 
 * GLOBUS_GENERIC_MAPPING_TYPE callout and the GLOBUS_GENERIC_AUTHZ_TYPE
1981
 
 * callout; otherwise the default gridmap file will be used for mapping
1982
 
 * and no service-specific authorization will be done.
1983
 
 *
1984
 
 * If @a globus_gss_assist_map_and_authorize() uses a gridmap file, it
1985
 
 * first looks for a file defined by the value of the GRIDMAP environment
1986
 
 * variable. If that is not set, it falls back to $HOME/.gridmap.
1987
 
 *
1988
 
 * @param context
1989
 
 *     Security context to inspect for peer identity information.
1990
 
 * @param service
1991
 
 *     A NULL-terminated string containing the name of the service that
1992
 
 *     an authorization decision is being made for.
1993
 
 * @param desired_identity
1994
 
 *     Optional. If non-NULL, perform an authorization to act as the 
1995
 
 *     local user named by this NULL-terminated string.
1996
 
 * @param identity_buffer
1997
 
 *     A pointer to a string buffer into which will be copied the
1998
 
 *     local user name that the peer of the context is authorized to
1999
 
 *     act as.
2000
 
 * @param identity_buffer_length
2001
 
 *     Length of the @a identity_buffer array.
2002
 
 *
2003
 
 * @return
2004
 
 *     On success, @a globus_gss_assist_map_and_authorize() returns
2005
 
 *     GLOBUS_SUCCESS and copies the authorized local identity to the
2006
 
 *     @a identity_buffer parameter. If an error occurs,
2007
 
 *     @a globus_gss_assist_map_and_authorize() returns a globus_result_t
2008
 
 *     that can be resolved to an error object.
2009
 
 *
2010
 
 * @retval GLOBUS_SUCCESS
2011
 
 *     Success
2012
 
 * @retval GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_CALLOUT_CONFIG
2013
 
 *     Invalid authorization configuration file
2014
 
 * @retval GLOBUS_CALLOUT_ERROR_WITH_HASHTABLE     
2015
 
 *     Hash table operation failed.
2016
 
 * @retval GLOBUS_CALLOUT_ERROR_CALLOUT_ERROR
2017
 
 *     The callout itself returned a error.
2018
 
 * @retval GLOBUS_CALLOUT_ERROR_WITH_DL
2019
 
 *     Dynamic library operation failed.
2020
 
 * @retval GLOBUS_CALLOUT_ERROR_OUT_OF_MEMORY
2021
 
 *     Out of memory
2022
 
 * @retval GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR
2023
 
 *     A GSSAPI function returned an error
2024
 
 * @retval GLOBUS_GSI_GSS_ASSIST_GRIDMAP_LOOKUP_FAILED
2025
 
 *     Gridmap lookup failure
2026
 
 * @retval GLOBUS_GSI_GSS_ASSIST_BUFFER_TOO_SMALL
2027
 
 *     Caller provided insufficient buffer space for local identity
2028
 
 */
2029
 
globus_result_t
2030
 
globus_gss_assist_map_and_authorize(
2031
 
    gss_ctx_id_t                        context,
2032
 
    char *                              service,
2033
 
    char *                              desired_identity,
2034
 
    char *                              identity_buffer,
2035
 
    unsigned int                        identity_buffer_length)
2036
 
{
2037
 
    globus_object_t *                   error;
2038
 
    globus_result_t                     result = GLOBUS_SUCCESS;
2039
 
    static globus_bool_t                initialized = GLOBUS_FALSE;
2040
 
    static globus_callout_handle_t      authz_handle = NULL;
2041
 
 
2042
 
    static char *                       _function_name_ =
2043
 
        "globus_gss_assist_map_and_authorize";
2044
 
    
2045
 
    globus_mutex_lock(&globus_i_gsi_gss_assist_mutex);
2046
 
    {
2047
 
        if(initialized == GLOBUS_FALSE)
2048
 
        {
2049
 
            char *                      filename;
2050
 
            result = GLOBUS_GSI_SYSCONFIG_GET_AUTHZ_CONF_FILENAME(&filename);
2051
 
            
2052
 
            if(result != GLOBUS_SUCCESS)
2053
 
            {
2054
 
                error = globus_error_get(result);
2055
 
        
2056
 
                if(globus_error_match(
2057
 
                       error,
2058
 
                       GLOBUS_GSI_SYSCONFIG_MODULE,
2059
 
                       GLOBUS_GSI_SYSCONFIG_ERROR_GETTING_AUTHZ_FILENAME)
2060
 
                   == GLOBUS_TRUE)
2061
 
                {
2062
 
                    globus_object_free(error);
2063
 
                }
2064
 
                else
2065
 
                {
2066
 
                    result = globus_error_put(error);
2067
 
                    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
2068
 
                    return result;
2069
 
                }
2070
 
            }
2071
 
            else
2072
 
            {
2073
 
                result = globus_callout_handle_init(&authz_handle);
2074
 
            
2075
 
                if(result != GLOBUS_SUCCESS)
2076
 
                {
2077
 
                    free(filename);
2078
 
                    GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2079
 
                        result,
2080
 
                        GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_CALLOUT_CONFIG);
2081
 
                    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
2082
 
                    return result;
2083
 
                }
2084
 
            
2085
 
                result = globus_callout_read_config(authz_handle, filename);
2086
 
 
2087
 
                free(filename);
2088
 
            
2089
 
                if(result != GLOBUS_SUCCESS)
2090
 
                {
2091
 
                    GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2092
 
                        result,
2093
 
                        GLOBUS_GSI_GSS_ASSIST_ERROR_INITIALIZING_CALLOUT_HANDLE);
2094
 
                    globus_callout_handle_destroy(authz_handle);
2095
 
                    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
2096
 
                    return result;
2097
 
                }
2098
 
            }
2099
 
            initialized = GLOBUS_TRUE;
2100
 
        }
2101
 
    }
2102
 
    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
2103
 
 
2104
 
    
2105
 
    if(authz_handle == NULL)
2106
 
    {
2107
 
        return globus_l_gss_assist_gridmap_lookup(
2108
 
            context,
2109
 
            service,
2110
 
            desired_identity,
2111
 
            identity_buffer,
2112
 
            identity_buffer_length);
2113
 
    }
2114
 
    else
2115
 
    {            
2116
 
        result = globus_callout_call_type(authz_handle,
2117
 
                                          GLOBUS_GENERIC_MAPPING_TYPE,
2118
 
                                          context,
2119
 
                                          service,
2120
 
                                          desired_identity,
2121
 
                                          identity_buffer,
2122
 
                                          identity_buffer_length);
2123
 
        
2124
 
        if(result != GLOBUS_SUCCESS)
2125
 
        {
2126
 
            error = globus_error_get(result);
2127
 
            
2128
 
            if(globus_error_match(
2129
 
                   error,
2130
 
                   GLOBUS_CALLOUT_MODULE,
2131
 
                   GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED)
2132
 
               == GLOBUS_TRUE)
2133
 
            {
2134
 
                globus_object_free(error);
2135
 
                result = globus_l_gss_assist_gridmap_lookup(
2136
 
                    context,
2137
 
                    service,
2138
 
                    desired_identity,
2139
 
                    identity_buffer,
2140
 
                    identity_buffer_length);
2141
 
                goto error;
2142
 
            }
2143
 
            else
2144
 
            {
2145
 
                result = globus_error_put(error);
2146
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2147
 
                    result,
2148
 
                    GLOBUS_GSI_GSS_ASSIST_CALLOUT_ERROR);
2149
 
                goto error;
2150
 
            }
2151
 
        }
2152
 
 
2153
 
        result = globus_callout_call_type(authz_handle,
2154
 
                                          GLOBUS_GENERIC_AUTHZ_TYPE,
2155
 
                                          context,
2156
 
                                          service);        
2157
 
        if(result != GLOBUS_SUCCESS)
2158
 
        {
2159
 
            error = globus_error_get(result);
2160
 
            
2161
 
            if(globus_error_match(
2162
 
                   error,
2163
 
                   GLOBUS_CALLOUT_MODULE,
2164
 
                   GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED)
2165
 
               == GLOBUS_FALSE)
2166
 
            {
2167
 
                result = globus_error_put(error);
2168
 
                GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2169
 
                    result,
2170
 
                    GLOBUS_GSI_GSS_ASSIST_CALLOUT_ERROR);
2171
 
                goto error;
2172
 
            }
2173
 
            else
2174
 
            {
2175
 
                result = GLOBUS_SUCCESS;
2176
 
            }
2177
 
 
2178
 
            globus_object_free(error);
2179
 
        }
2180
 
    }
2181
 
    
2182
 
 
2183
 
 error:
2184
 
    return result;
2185
 
}
2186
 
/* globus_gss_assist_map_and_authorize */
2187
 
 
2188
 
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
2189
 
static
2190
 
globus_result_t
2191
 
globus_l_gss_assist_gridmap_lookup(
2192
 
    gss_ctx_id_t                        context,
2193
 
    char *                              service,
2194
 
    char *                              desired_identity,
2195
 
    char *                              identity_buffer,
2196
 
    unsigned int                        identity_buffer_length)
2197
 
{
2198
 
    gss_name_t                          peer;
2199
 
    gss_buffer_desc                     peer_name_buffer;
2200
 
    OM_uint32                           major_status;
2201
 
    OM_uint32                           minor_status;
2202
 
    int                                 initiator;
2203
 
    globus_result_t                     result = GLOBUS_SUCCESS;
2204
 
    int                                 rc;
2205
 
    char *                              local_identity;
2206
 
    static char *                       _function_name_ =
2207
 
        "globus_l_gss_assist_gridmap_lookup";
2208
 
    
2209
 
    major_status = gss_inquire_context(&minor_status,
2210
 
                                       context,
2211
 
                                       GLOBUS_NULL,
2212
 
                                       GLOBUS_NULL,
2213
 
                                       GLOBUS_NULL,
2214
 
                                       GLOBUS_NULL,
2215
 
                                       GLOBUS_NULL,
2216
 
                                       &initiator,
2217
 
                                       GLOBUS_NULL);
2218
 
 
2219
 
    if(GSS_ERROR(major_status))
2220
 
    {
2221
 
        result =  minor_status;
2222
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2223
 
            result,
2224
 
            GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
2225
 
        goto error;
2226
 
    }
2227
 
 
2228
 
    major_status = gss_inquire_context(&minor_status,
2229
 
                                       context,
2230
 
                                       initiator ? GLOBUS_NULL : &peer,
2231
 
                                       initiator ? &peer : GLOBUS_NULL,
2232
 
                                       GLOBUS_NULL,
2233
 
                                       GLOBUS_NULL,
2234
 
                                       GLOBUS_NULL,
2235
 
                                       GLOBUS_NULL,
2236
 
                                       GLOBUS_NULL);
2237
 
 
2238
 
    if(GSS_ERROR(major_status))
2239
 
    {
2240
 
        result =  minor_status;
2241
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2242
 
            result,
2243
 
            GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
2244
 
        goto error;
2245
 
    }
2246
 
    
2247
 
    major_status = gss_display_name(&minor_status,
2248
 
                                    peer,
2249
 
                                    &peer_name_buffer,
2250
 
                                    GLOBUS_NULL);
2251
 
    if(GSS_ERROR(major_status))
2252
 
    {
2253
 
        result =  minor_status;
2254
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2255
 
            result,
2256
 
            GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
2257
 
        gss_release_name(&minor_status, &peer);
2258
 
        goto error;
2259
 
    }
2260
 
 
2261
 
    gss_release_name(&minor_status, &peer);        
2262
 
    
2263
 
    if(desired_identity == NULL)
2264
 
    {
2265
 
        rc = globus_gss_assist_gridmap(
2266
 
            peer_name_buffer.value, 
2267
 
            &local_identity);
2268
 
        
2269
 
        if(rc != 0)
2270
 
        {
2271
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2272
 
                result,
2273
 
                GLOBUS_GSI_GSS_ASSIST_GRIDMAP_LOOKUP_FAILED,
2274
 
                (_GASL("Could not map %s\n"), peer_name_buffer.value));
2275
 
            goto release_peer_name_buffer;
2276
 
        }
2277
 
 
2278
 
        if(strlen(local_identity) + 1 > identity_buffer_length)
2279
 
        {
2280
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2281
 
                result,
2282
 
                GLOBUS_GSI_GSS_ASSIST_BUFFER_TOO_SMALL,
2283
 
                (_GASL("Local identity length: %d Buffer length: %d\n"),
2284
 
                 strlen(local_identity), identity_buffer_length));
2285
 
        }
2286
 
        else
2287
 
        {
2288
 
            strcpy(identity_buffer, local_identity);
2289
 
        }
2290
 
        free(local_identity);
2291
 
    }
2292
 
    else
2293
 
    {
2294
 
        rc = globus_gss_assist_userok(peer_name_buffer.value,
2295
 
                                      desired_identity);
2296
 
        if(rc != 0)
2297
 
        {
2298
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2299
 
                result,
2300
 
                GLOBUS_GSI_GSS_ASSIST_GRIDMAP_LOOKUP_FAILED,
2301
 
                (_GASL("Could not map %s to %s\n"),
2302
 
                 peer_name_buffer.value,
2303
 
                 desired_identity));
2304
 
            goto release_peer_name_buffer;
2305
 
        }
2306
 
 
2307
 
        if(strlen(desired_identity) + 1 > identity_buffer_length)
2308
 
        {
2309
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2310
 
                result,
2311
 
                GLOBUS_GSI_GSS_ASSIST_BUFFER_TOO_SMALL,
2312
 
                (_GASL("Desired identity length: %d Buffer length: %d\n"),
2313
 
                 strlen(desired_identity), identity_buffer_length));
2314
 
        }
2315
 
        else
2316
 
        {
2317
 
            strcpy(identity_buffer, desired_identity);
2318
 
        }
2319
 
    }
2320
 
 
2321
 
release_peer_name_buffer:
2322
 
    gss_release_buffer(&minor_status, &peer_name_buffer);
2323
 
 
2324
 
 error:
2325
 
    return result;
2326
 
}
2327
 
 
2328
 
/**
2329
 
 * Determine length of the next line on the file stream
2330
 
 *
2331
 
 * Scans the input stream to determine the length of the next line
2332
 
 * ending with \n or the length until the end of the file. The
2333
 
 * value is returned in the integer pointed to by @a len. If the file
2334
 
 * pointer is currently at end-of-file, *len will be set to 0.
2335
 
 * 
2336
 
 * @param fp
2337
 
 *     File pointer to inspect
2338
 
 * @param len
2339
 
 *     Pointer to be set to the length
2340
 
 *
2341
 
 * @retval GLOBUS_SUCCESS
2342
 
 *     Success
2343
 
 * @retval GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP
2344
 
 *     Error with gridmap
2345
 
 */
2346
 
static
2347
 
globus_result_t
2348
 
globus_l_gss_assist_line_length(
2349
 
    FILE *                              fp,
2350
 
    size_t *                            len)
2351
 
{
2352
 
    globus_result_t                     result = GLOBUS_SUCCESS;
2353
 
    fpos_t                              pos;
2354
 
    int                                 line_len = -1;
2355
 
    int                                 rc;
2356
 
    static char *                       _function_name_ =
2357
 
        "globus_l_gss_assist_line_length";
2358
 
 
2359
 
    *len = 0;
2360
 
 
2361
 
    rc = fgetpos(fp, &pos);
2362
 
    if (rc < 0)
2363
 
    {
2364
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2365
 
            result,
2366
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
2367
 
            (_GASL("Couldn't determine position in file.")));
2368
 
        goto fgetpos_failed;
2369
 
    }
2370
 
 
2371
 
    rc = fscanf(fp, "%*[^\n]%*1[\n]%n", &line_len);
2372
 
    if (line_len == -1 && rc == 0)
2373
 
    {
2374
 
       /* match failure; see if we have an empty line */
2375
 
       rc = fscanf(fp, "%*1[\n]%n", &line_len);
2376
 
    }
2377
 
 
2378
 
    if (rc < 0 && !feof(fp))
2379
 
    {
2380
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2381
 
            result,
2382
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
2383
 
            (_GASL("Couldn't determine end of line in file.")));
2384
 
        goto fscanf_failed;
2385
 
    }
2386
 
    else if (feof(fp))
2387
 
    {
2388
 
        /* Assume end-of-file without newline */
2389
 
        clearerr(fp);
2390
 
        line_len = ftell(fp);
2391
 
    }
2392
 
 
2393
 
    rc = fsetpos(fp, &pos);
2394
 
    if (rc < 0)
2395
 
    {
2396
 
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2397
 
            result,
2398
 
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
2399
 
            (_GASL("Couldn't set position in file.")));
2400
 
        goto fsetpos_failed;
2401
 
    }
2402
 
 
2403
 
    *len = line_len;
2404
 
 
2405
 
fsetpos_failed:
2406
 
fscanf_failed:
2407
 
fgetpos_failed:
2408
 
    return result;
2409
 
}
2410
 
/* globus_l_gss_assist_line_length() */
2411
 
#endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */