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

« back to all changes in this revision

Viewing changes to gridmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Mattias Ellert
  • Date: 2009-04-18 20:17:33 UTC
  • Revision ID: james.westby@ubuntu.com-20090418201733-xl4r26mgda1shx4q
Tags: upstream-4.0
ImportĀ upstreamĀ versionĀ 4.0

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.23.4.1 $
 
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
 
 
113
#endif
 
114
 
 
115
/**
 
116
 * @name Gridmap
 
117
 */
 
118
/* @{ */
 
119
/**
 
120
 * @ingroup globus_gsi_gss_assist
 
121
 * 
 
122
 * Routines callable from globus based code to 
 
123
 * map a globusID to a local unix user
 
124
 *
 
125
 * GRIDMAP environment variable pointing at the
 
126
 * map file. Defaults to ~/.gridmap 
 
127
 *
 
128
 * A gridmap file is required if being run as root. 
 
129
 * if being run as a user,it is not required, and defaults to 
 
130
 * the current user who is running the command. 
 
131
 *
 
132
 * This is the same file used by the gssapi_cleartext
 
133
 * but will be used with other gssapi implementations which 
 
134
 * do not use the gridmap file. 
 
135
 *
 
136
 * @param globusidp
 
137
 *        the GSSAPI name from the client who requested
 
138
 *        authentication
 
139
 * @param useridp
 
140
 *        the resulting user ID name for the local system
 
141
 *
 
142
 * @return 
 
143
 *        0 on success
 
144
 *        -1 if bad arguments
 
145
 *        1 on error
 
146
 */
 
147
int 
 
148
globus_gss_assist_gridmap(
 
149
    char *                              globusidp,
 
150
    char **                             useridp) 
 
151
{
 
152
    globus_result_t                     result = GLOBUS_SUCCESS;
 
153
    globus_i_gss_assist_gridmap_line_t *
 
154
                                        gline = NULL;
 
155
 
 
156
    static char *                       _function_name_ =
 
157
    "globus_gss_assist_gridmap";
 
158
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
159
 
 
160
    /* Check arguments */
 
161
    if ((globusidp == NULL) || (useridp == NULL))
 
162
    {
 
163
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
164
            result,
 
165
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
 
166
            (_GASL("Params passed to function are NULL")));
 
167
        goto exit;
 
168
    }
 
169
 
 
170
    *useridp = NULL;
 
171
 
 
172
    result = globus_i_gss_assist_gridmap_find_dn(globusidp, &gline);
 
173
    if(result != GLOBUS_SUCCESS)
 
174
    {
 
175
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
176
            result,
 
177
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
178
        goto exit;
 
179
    }
 
180
 
 
181
    if (gline != NULL)
 
182
    {
 
183
        if ((gline->user_ids == NULL) ||
 
184
            (gline->user_ids[0] == NULL))
 
185
        {
 
186
            /*
 
187
             * If we get here then something in this code is broken
 
188
             * or the gridmap file is badly formatted or, most likely,
 
189
             * both.
 
190
             */
 
191
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
192
                result,
 
193
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
194
                (_GASL("Invalid (NULL) user id values")));
 
195
            goto exit;
 
196
        }
 
197
 
 
198
        /* First user id is default */
 
199
        *useridp = strdup(gline->user_ids[0]);
 
200
 
 
201
        globus_i_gss_assist_gridmap_line_free(gline);
 
202
 
 
203
        if (*useridp == NULL)
 
204
        {
 
205
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
206
                result,
 
207
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
208
                (_GASL("Duplicate string operation failed")));
 
209
            goto exit;
 
210
        }
 
211
    }
 
212
    else
 
213
    {
 
214
        char *                          gridmap_filename = NULL;
 
215
 
 
216
        GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
 
217
 
 
218
        /* No entry found in gridmap file for this user */
 
219
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
220
            result,
 
221
            GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
 
222
            (_GASL("The DN: %s could not be mapped to a valid user in the "
 
223
             "gridmap file: %s."),
 
224
             globusidp,
 
225
             gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
 
226
 
 
227
        free(gridmap_filename);
 
228
        goto exit;
 
229
    }
 
230
 
 
231
 exit:
 
232
 
 
233
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
234
    if(result == GLOBUS_SUCCESS)
 
235
    {
 
236
        return 0;
 
237
    }
 
238
    else
 
239
    {
 
240
        globus_object_t *               error_obj;
 
241
        error_obj = globus_error_get(result);
 
242
        globus_object_free(error_obj);
 
243
 
 
244
        return 1;
 
245
    }
 
246
 
247
/* globus_gss_assist_gridmap() */
 
248
/* @} */
 
249
 
 
250
/**
 
251
 * @name User OK
 
252
 */
 
253
/* @{ */
 
254
/**
 
255
 * @ingroup globus_gsi_gss_assist
 
256
 * Check to see if a particular globusid is authorized to access
 
257
 * the given local user account.
 
258
 *
 
259
 * @param globusid
 
260
 *        the globus id in string form - this should be the user's subject
 
261
 * @param userid
 
262
 *        the local account that access is sought for
 
263
 *
 
264
 * @return
 
265
 *        0 on success (authorization allowed)
 
266
 *        -1 if bad arguments
 
267
 *        1 on error
 
268
 */
 
269
int
 
270
globus_gss_assist_userok(
 
271
    char *                              globusid,
 
272
    char *                              userid)
 
273
{
 
274
    char *                              gridmap_filename = NULL;
 
275
    globus_result_t                     result = GLOBUS_SUCCESS;
 
276
    globus_i_gss_assist_gridmap_line_t *                        
 
277
                                        gline = NULL;
 
278
    char **                             useridp;
 
279
    static char *                       _function_name_ =
 
280
        "globus_gss_assist_userok";
 
281
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
282
 
 
283
    /* Check arguments */
 
284
    if ((globusid == NULL) ||
 
285
        (userid == NULL))
 
286
    {
 
287
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
288
            result,
 
289
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
 
290
            (_GASL("Arguments passed to function are NULL")));
 
291
        goto exit;
 
292
    }
 
293
    
 
294
    result = globus_i_gss_assist_gridmap_find_dn(globusid, &gline);
 
295
    if(result != GLOBUS_SUCCESS)
 
296
    {
 
297
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
298
            result,
 
299
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
300
        goto exit;
 
301
    }
 
302
 
 
303
    if (gline == NULL)
 
304
    {
 
305
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
306
            result,
 
307
            GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
 
308
            (_GASL("The DN: %s does not map to the username: %s"),
 
309
             globusid,
 
310
             userid));
 
311
        goto exit;
 
312
    }
 
313
    if (gline->user_ids == NULL)
 
314
    {
 
315
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
316
            result,
 
317
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
318
            (_GASL("The gridmap is malformated.  No user id's could be be found.")));
 
319
        goto exit;
 
320
    }
 
321
 
 
322
    for (useridp = gline->user_ids; *useridp != NULL; useridp++)
 
323
    {
 
324
        if (strcmp(*useridp, userid) == 0)
 
325
        {
 
326
            goto exit;
 
327
        }
 
328
    }
 
329
 
 
330
    GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
 
331
    GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
332
        result,
 
333
        GLOBUS_GSI_GSS_ASSIST_ERROR_USER_ID_DOESNT_MATCH,
 
334
        (_GASL("The user id: %s, doesn't match the the DN: %s, in the "
 
335
         "gridmap file: %s"),
 
336
         globusid,
 
337
         userid,
 
338
         gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
 
339
    free(gridmap_filename);
 
340
 
 
341
 exit:
 
342
 
 
343
    if(gline)
 
344
    {
 
345
        globus_i_gss_assist_gridmap_line_free(gline);
 
346
    }
 
347
 
 
348
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
349
    if(result == GLOBUS_SUCCESS)
 
350
    {
 
351
        return 0;
 
352
    }
 
353
    else
 
354
    {
 
355
        globus_object_t *               error_obj;
 
356
        error_obj = globus_error_get(result);
 
357
        globus_object_free(error_obj);
 
358
 
 
359
        return 1;
 
360
    }
 
361
 
362
/* globus_gss_assist_userok() */
 
363
/* @} */
 
364
 
 
365
/**
 
366
 * @name Map Local User
 
367
 */
 
368
/* @{ */
 
369
/**
 
370
 * @ingroup globus_gsi_gss_assist
 
371
 * Routine for returning the default globus ID associated with
 
372
 * a local user name. This is somewhat of a hack since there is
 
373
 * not a guarenteed one-to-one mapping. What we do is look for
 
374
 * the first entry in the gridmap file that has the local
 
375
 * user as the default login. If the user is not a default on any 
 
376
 * entry, we find the first entry in which the user exists as a 
 
377
 * secondary mapping.
 
378
 *
 
379
 * @param local_user
 
380
 *        the local username to find the DN for
 
381
 * @param globusidp
 
382
 *        the first DN found that reverse maps from the local_user
 
383
 *
 
384
 * @return
 
385
 *        0 on success, otherwise an error object identifier is returned.
 
386
 *        use globus_error_get to get the error object from the id.  The
 
387
 *        resulting error object must be freed using globus_object_free
 
388
 *        when it is no longer needed.
 
389
 *
 
390
 * @see globus_error_get
 
391
 * @see globus_object_free
 
392
 */
 
393
int 
 
394
globus_gss_assist_map_local_user(
 
395
    char *                              local_user,
 
396
    char **                             globusidp) 
 
397
{
 
398
    char *                              gridmap_filename = NULL;
 
399
    globus_result_t                     result = GLOBUS_SUCCESS;
 
400
    globus_i_gss_assist_gridmap_line_t *                        
 
401
                                        gline = NULL;
 
402
    static char *                       _function_name_ =
 
403
        "globus_gss_assist_map_local_user";
 
404
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
405
 
 
406
    /* Check arguments */
 
407
    if ((local_user == NULL) ||
 
408
        (globusidp == NULL))
 
409
    {
 
410
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
411
            result,
 
412
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
 
413
            (_GASL("Arguments passed to the function are NULL.")));
 
414
        goto exit;
 
415
    }
 
416
 
 
417
    *globusidp = NULL;
 
418
 
 
419
    result = globus_i_gss_assist_gridmap_find_local_user(local_user, &gline);
 
420
    if(result != GLOBUS_SUCCESS)
 
421
    {
 
422
        /*
 
423
         * We failed to open the gridmap file.
 
424
         */
 
425
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
426
            result,
 
427
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
428
        goto exit;
 
429
    }
 
430
 
 
431
    if (gline != NULL)
 
432
    {
 
433
        if (gline->dn == NULL)
 
434
        {
 
435
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
436
                result,
 
437
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
438
                (_GASL("The gridmap file: %s is formatted incorrectly.  No "
 
439
                 "distinguished names could be found.")));
 
440
            goto exit;
 
441
        }
 
442
 
 
443
        /* First user id is default */
 
444
        *globusidp = strdup(gline->dn);
 
445
 
 
446
        if (*globusidp == NULL)
 
447
        {
 
448
            /* strdup() failed */
 
449
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
450
                result,
 
451
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
452
                (_GASL("The string duplication operation failed.")));
 
453
            goto exit;
 
454
        }
 
455
    }
 
456
    else
 
457
    {
 
458
        GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
 
459
        /* No entry found in gridmap file for this user */
 
460
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
461
            result,
 
462
            GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
 
463
            (_GASL("No DN entry found for user: %s in gridmap file: %s"),
 
464
             local_user,
 
465
             gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
 
466
        free(gridmap_filename);
 
467
        goto exit;
 
468
    }
 
469
 
 
470
 exit:
 
471
 
 
472
    if(gline)
 
473
    {
 
474
        globus_i_gss_assist_gridmap_line_free(gline);
 
475
    }
 
476
 
 
477
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
478
    if(result == GLOBUS_SUCCESS)
 
479
    {
 
480
        return 0;
 
481
    }
 
482
    else
 
483
    {
 
484
        globus_object_t *               error_obj;
 
485
        error_obj = globus_error_get(result);
 
486
        globus_object_free(error_obj);
 
487
 
 
488
        return 1;
 
489
    }
 
490
 
491
/* globus_gss_assist_map_local_user() */
 
492
/* @} */
 
493
 
 
494
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
 
495
 
 
496
/**
 
497
 * @name Gridmap Find DN
 
498
 */
 
499
/* @{ */
 
500
/**
 
501
 * @ingroup globus_i_gsi_gss_assist
 
502
 * Locate the entry for the given DN in the default gridmap file
 
503
 *
 
504
 * @param dn
 
505
 *        the distinguished name to search for
 
506
 * @param gline
 
507
 *        gives the line information 
 
508
 *
 
509
 * @return
 
510
 *        0 on success, otherwise an error object identifier is returned.
 
511
 *        use globus_error_get to get the error object from the id.  The
 
512
 *        resulting error object must be freed using globus_object_free
 
513
 *        when it is no longer needed.
 
514
 *
 
515
 * @see globus_error_get
 
516
 * @see globus_object_free
 
517
 */
 
518
static
 
519
globus_result_t
 
520
globus_i_gss_assist_gridmap_find_dn(
 
521
    const char * const                  dn,
 
522
    globus_i_gss_assist_gridmap_line_t **                       
 
523
                                        gline)
 
524
{
 
525
    char *                              gridmap_filename = NULL;
 
526
    globus_result_t                     result = GLOBUS_SUCCESS;
 
527
    char *                              open_mode = "r";
 
528
    FILE *                              gmap_stream = NULL;
 
529
    int                                 found = 0;
 
530
    globus_i_gss_assist_gridmap_line_t *                        
 
531
                                        gline_tmp = NULL;
 
532
    static char *                       _function_name_ =
 
533
        "globus_i_gss_assist_gridmap_find_dn";
 
534
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
535
 
 
536
 
 
537
    /* Check arguments */
 
538
    if (dn == NULL)
 
539
    {
 
540
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
541
            result,
 
542
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
 
543
            (_GASL("The DN passed to function is NULL.")));
 
544
        goto exit;
 
545
    }
 
546
 
 
547
    result = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
 
548
    if(result != GLOBUS_SUCCESS)
 
549
    {
 
550
        gridmap_filename = NULL;
 
551
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
552
            result,
 
553
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
554
        goto exit;
 
555
    }
 
556
 
 
557
    gmap_stream = fopen(gridmap_filename, open_mode);
 
558
 
 
559
    if (gmap_stream == NULL)
 
560
    {
 
561
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
562
            result,
 
563
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
564
            (_GASL("Couldn't open gridmap file: %s for reading."),
 
565
             gridmap_filename));
 
566
        goto exit;
 
567
    }
 
568
 
 
569
    free(gridmap_filename);
 
570
    gridmap_filename = NULL;
 
571
 
 
572
    do
 
573
    {
 
574
        char                            line[1024];
 
575
 
 
576
        if (fgets(line, sizeof(line), gmap_stream) == NULL)
 
577
        {
 
578
            break;              /* EOF or error */
 
579
        }
 
580
 
 
581
        result = globus_i_gss_assist_gridmap_parse_line(line, &gline_tmp);
 
582
        if (result != GLOBUS_SUCCESS)
 
583
        {
 
584
            GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
585
                result,
 
586
                GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
587
            continue;           /* Parse error */
 
588
        }
 
589
 
 
590
        if ((gline_tmp != NULL) &&
 
591
            (globus_i_gsi_cert_utils_dn_cmp(dn, gline_tmp->dn) == 0))
 
592
        {
 
593
            found = 1;
 
594
        }
 
595
        else
 
596
        {
 
597
            globus_i_gss_assist_gridmap_line_free(gline_tmp);
 
598
        }
 
599
 
 
600
    } while (!found);
 
601
 
 
602
    fclose(gmap_stream);
 
603
    gmap_stream = NULL;
 
604
 
 
605
    if (found)
 
606
    {
 
607
        *gline = gline_tmp;
 
608
    }
 
609
    else
 
610
    {
 
611
        *gline = NULL;
 
612
    }
 
613
 
 
614
 exit:
 
615
 
 
616
    if (gridmap_filename != NULL)
 
617
    {
 
618
        free(gridmap_filename);
 
619
    }
 
620
 
 
621
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
622
    return result;
 
623
 
624
/* gridmap_find_dn() */
 
625
/* @} */
 
626
 
 
627
/**
 
628
 * @name Find Local User
 
629
 */
 
630
/* @{ */
 
631
/**
 
632
 * @ingroup globus_i_gsi_gss_assist
 
633
 * Locate the first entry with the given local user as the default in the
 
634
 * default gridmap file.  If the user is not a default on any entry, locate the
 
635
 * first entry in which the user exists as a secondary mapping.
 
636
 *
 
637
 * @param local_user
 
638
 *        the name to search for
 
639
 * @param gline
 
640
 *        the resulting gridmap_line_t contianing the user and DN information
 
641
 *
 
642
 * @return
 
643
 *        0 on success, otherwise an error object identifier is returned.
 
644
 *        use globus_error_get to get the error object from the id.  The
 
645
 *        resulting error object must be freed using globus_object_free
 
646
 *        when it is no longer needed.
 
647
 *
 
648
 * @see globus_error_get
 
649
 * @see globus_object_free
 
650
 */
 
651
static
 
652
globus_result_t
 
653
globus_i_gss_assist_gridmap_find_local_user(
 
654
    const char * const                  local_user,
 
655
    globus_i_gss_assist_gridmap_line_t **                       
 
656
                                        gline)
 
657
{
 
658
    char *                              gridmap_filename = NULL;
 
659
    char *                              open_mode = "r";
 
660
    FILE *                              gmap_stream = NULL;
 
661
    int                                 found = 0;
 
662
    globus_i_gss_assist_gridmap_line_t *                        
 
663
                                        gline_tmp;
 
664
    char **                             useridp;
 
665
    char *                              nondefault_line = NULL;
 
666
    globus_result_t                     result = GLOBUS_SUCCESS;
 
667
    static char *                       _function_name_ =
 
668
        "globus_i_gss_assist_gridmap_find_local_user";
 
669
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
670
 
 
671
    /* Check arguments */
 
672
    if (local_user == NULL)
 
673
    {
 
674
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
675
            result,
 
676
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
 
677
            (_GASL("Arguments passed to function are NULL.")));
 
678
        goto exit;
 
679
    }
 
680
 
 
681
    result = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
 
682
    if(result != GLOBUS_SUCCESS)
 
683
    {
 
684
        gridmap_filename = NULL;
 
685
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
686
            result,
 
687
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
688
        goto exit;
 
689
    }
 
690
            
 
691
    gmap_stream = fopen(gridmap_filename, open_mode);
 
692
 
 
693
    if (gmap_stream == NULL)
 
694
    {
 
695
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
696
            result,
 
697
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
698
            (_GASL("Can't open the file: %s"), gridmap_filename));
 
699
        goto exit;
 
700
    }
 
701
 
 
702
    do
 
703
    {
 
704
        char                            line[1024];
 
705
        char                            save_line[1024];
 
706
        
 
707
        if (fgets(line, sizeof(line), gmap_stream) == NULL)
 
708
        {
 
709
            break;              /* EOF or error */
 
710
        }
 
711
 
 
712
        strncpy(save_line, line, sizeof(save_line));
 
713
        
 
714
        result = globus_i_gss_assist_gridmap_parse_line(line, &gline_tmp);
 
715
        if(result != GLOBUS_SUCCESS)
 
716
        {
 
717
            continue;           /* Parse error */
 
718
        }
 
719
 
 
720
        if (gline_tmp == NULL)
 
721
        {
 
722
            /* Empty line */
 
723
            continue;
 
724
        }
 
725
 
 
726
        for(useridp = gline_tmp->user_ids; 
 
727
            *useridp != NULL && !found; 
 
728
            useridp++)
 
729
        {
 
730
            if(strcmp(local_user, *useridp) == 0)
 
731
            {
 
732
                /* check all names, but only stop looking if we match a 
 
733
                 * default name.  save the first nondefault match til 
 
734
                 * we've checked all the defaults */
 
735
                if(*useridp == gline_tmp->user_ids[0])
 
736
                {
 
737
                    found = 1;
 
738
                }
 
739
                else if(nondefault_line == NULL)
 
740
                {
 
741
                    nondefault_line = strdup(save_line);
 
742
                }
 
743
            }
 
744
        }
 
745
        if(!found)
 
746
        {
 
747
            globus_i_gss_assist_gridmap_line_free(gline_tmp);
 
748
        }
 
749
 
 
750
    } while (!found);
 
751
    
 
752
    if(nondefault_line != NULL)
 
753
    {
 
754
        result = globus_i_gss_assist_gridmap_parse_line(
 
755
            nondefault_line, &gline_tmp);
 
756
        free(nondefault_line);
 
757
        if(result != GLOBUS_SUCCESS)
 
758
        {
 
759
            goto exit;
 
760
        }
 
761
        found = 1;
 
762
    }        
 
763
 
 
764
    fclose(gmap_stream);
 
765
    gmap_stream = NULL;
 
766
 
 
767
    if (found)
 
768
        *gline = gline_tmp;
 
769
    else
 
770
        *gline = NULL;
 
771
 
 
772
 exit:
 
773
 
 
774
    if (gridmap_filename)
 
775
    {
 
776
        free(gridmap_filename);
 
777
    }
 
778
 
 
779
    if (gmap_stream)
 
780
        fclose(gmap_stream);
 
781
 
 
782
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
783
    return result;
 
784
 
785
/* gridmap_find_local_user() */
 
786
/* @} */
 
787
 
 
788
/**
 
789
 * @name Gridmap Parse Line
 
790
 */
 
791
/* @{ */
 
792
/**
 
793
 * @ingroup globus_i_gsi_gss_assist
 
794
 * 
 
795
 * Given a line from the gridmap file, parse it returning
 
796
 * a gridmap_line_t structure. line is modified during parsing.
 
797
 * The format of the line is expected to be:
 
798
 * <DN> <userid>[,<userid>[,<userid>...]]
 
799
 * Leading and trailing whitespace is ignored.
 
800
 * userids must only have a comma between them, no whitespace.
 
801
 * Anything after the userids is ignored.
 
802
 * Anything after an unescaped comment character is ignored.
 
803
 *
 
804
 * @param line
 
805
 *        the line to parse
 
806
 * @param gline
 
807
 *        the resulting parsed gridmap line structure
 
808
 *
 
809
 * @return
 
810
 *        0 on success, otherwise an error object identifier is returned.
 
811
 *        use globus_error_get to get the error object from the id.  The
 
812
 *        resulting error object must be freed using globus_object_free
 
813
 *        when it is no longer needed.
 
814
 *
 
815
 * @see globus_error_get
 
816
 * @see globus_object_free
 
817
 */
 
818
static
 
819
globus_result_t
 
820
globus_i_gss_assist_gridmap_parse_line(
 
821
    char *                              line,
 
822
    globus_i_gss_assist_gridmap_line_t **                       
 
823
                                        gline)
 
824
{
 
825
    char *                              dn_end;
 
826
    char *                              parsed_dn = NULL;
 
827
    char **                             userids = NULL;
 
828
    int                                 num_userids = 0;
 
829
    int                                 userid_slots = 0;
 
830
    globus_i_gss_assist_gridmap_line_t *                        
 
831
                                        gline_tmp = NULL;
 
832
    globus_result_t                     result = GLOBUS_SUCCESS;
 
833
    static char *                       _function_name_ =
 
834
        "globus_i_gss_assist_gridmap_parse_line";
 
835
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
836
    
 
837
    /* Check arguments */
 
838
    if ((line == NULL) ||
 
839
        (gline == NULL))
 
840
    {
 
841
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
842
            result,
 
843
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
844
            (_GASL("Arguments passed to function are NULL.")));
 
845
        goto exit;
 
846
    }
 
847
 
 
848
    /* Skip over leading whitespace */
 
849
    line += strspn(line, WHITESPACE_CHARS);
 
850
 
 
851
    /* Check for comment at start of line and ignore line if present */
 
852
    if (strchr(COMMENT_CHARS, *line) != NULL) 
 
853
    {
 
854
        /* Ignore line, return NULL gline */
 
855
        *gline = NULL;
 
856
        goto exit;
 
857
    }
 
858
        
 
859
    /* Check for empty line */
 
860
    if (*line == NUL)
 
861
    {
 
862
        /* Empty line, return NULL gline. */
 
863
        *gline = NULL;
 
864
        goto exit;
 
865
    }
 
866
 
 
867
    /* Is DN quoted? */
 
868
    if (strchr(QUOTING_CHARS, *line) != NULL)
 
869
    {
 
870
        /*
 
871
         * Yes, skip over opening quote and look for unescaped
 
872
         * closing double quote
 
873
         */
 
874
        line++;
 
875
        dn_end = line;
 
876
 
 
877
        do
 
878
        {
 
879
            /* If loop below resolves bug 4979 */
 
880
            if (strchr(ESCAPING_CHARS, *(dn_end - 1))) 
 
881
            {
 
882
                dn_end++;
 
883
            }
 
884
            
 
885
            dn_end += strcspn(dn_end, QUOTING_CHARS);
 
886
 
 
887
            if (*dn_end == NUL)
 
888
            {
 
889
                GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
890
                    result,
 
891
                    GLOBUS_GSI_GSS_ASSIST_ERROR_INVALID_GRIDMAP_FORMAT,
 
892
                    (_GASL("A closing quote is missing in the gridmap file, "
 
893
                     "on the line:\n%s\n"),
 
894
                     line));
 
895
                goto exit;
 
896
            }
 
897
 
 
898
            /* Make sure it's not escaped */
 
899
        }
 
900
        while (strchr(ESCAPING_CHARS, *(dn_end - 1)) != NULL);
 
901
    }
 
902
    else
 
903
    {
 
904
        /* No, just find next whitespace */
 
905
        dn_end = line + strcspn(line, WHITESPACE_CHARS);
 
906
 
 
907
        if (*dn_end == NUL)
 
908
        {
 
909
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
910
                result,
 
911
                GLOBUS_GSI_GSS_ASSIST_ERROR_INVALID_GRIDMAP_FORMAT,
 
912
                (_GASL("Nothing follows the DN on the line:\n%s\n"),
 
913
                 line));
 
914
            goto exit;
 
915
        }
 
916
    }
 
917
 
 
918
    /* NUL terminate DN and parse */
 
919
    *dn_end = NUL;
 
920
 
 
921
    result = globus_i_gss_assist_gridmap_parse_globusid(line, &parsed_dn);
 
922
    if(result != GLOBUS_SUCCESS)
 
923
    {
 
924
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
925
            result,
 
926
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
927
        goto exit;
 
928
    }
 
929
 
 
930
    /* Skip over closing delim and any whitespace after DN */
 
931
    line = dn_end + 1;
 
932
    line += strspn(line, WHITESPACE_CHARS);
 
933
 
 
934
    /* Parse list of unix user ID seperated by USERID_SEP_CHARS */
 
935
    while (*line != NUL)
 
936
    {
 
937
        int                                     userid_len;
 
938
 
 
939
        /* Find end of this userid */
 
940
        userid_len = strcspn(line, USERID_TERMINATOR_CHARS);
 
941
 
 
942
        /* Make sure we have a slot and if not allocate it */
 
943
        if ((num_userids + 1 /* new entry */+ 1 /* for NULL */) > userid_slots)
 
944
        {
 
945
            char **userids_tmp;
 
946
            userid_slots += USERID_CHUNK_SIZE;
 
947
            userids_tmp = realloc(userids, userid_slots * sizeof(char *));
 
948
 
 
949
            if (!userids_tmp)
 
950
            {
 
951
                result = globus_error_put(globus_error_wrap_errno_error(
 
952
                    GLOBUS_GSI_GSS_ASSIST_MODULE,
 
953
                    errno,
 
954
                    GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
 
955
                    __FILE__,
 
956
                    _function_name_,
 
957
                    __LINE__,
 
958
                    _GASL("Could not allocate enough memory")));
 
959
                goto error_exit;
 
960
            }
 
961
 
 
962
            userids = userids_tmp;
 
963
        }
 
964
  
 
965
        userids[num_userids] = malloc(userid_len + 1 /* for NUL */);
 
966
 
 
967
        if (!userids[num_userids])
 
968
        {
 
969
            result = globus_error_put(globus_error_wrap_errno_error(
 
970
                GLOBUS_GSI_GSS_ASSIST_MODULE,
 
971
                errno,
 
972
                GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
 
973
                __FILE__,
 
974
                _function_name_,
 
975
                __LINE__,
 
976
                _GASL("Could not allocate enough memory")));
 
977
            goto error_exit;
 
978
        }
 
979
 
 
980
        strncpy(userids[num_userids], line, userid_len);
 
981
        userids[num_userids][userid_len] = NUL;
 
982
 
 
983
        num_userids++;
 
984
        userids[num_userids] = NULL;
 
985
 
 
986
        line += userid_len;
 
987
        line += strspn(line, USERID_TERMINATOR_CHARS);
 
988
    }
 
989
 
 
990
    /* Ok, build our gridmap_line_t structure */
 
991
    gline_tmp = malloc(sizeof(*gline_tmp));
 
992
 
 
993
    if (gline_tmp == NULL)
 
994
    {
 
995
        result = globus_error_put(globus_error_wrap_errno_error(
 
996
            GLOBUS_GSI_GSS_ASSIST_MODULE,
 
997
            errno,
 
998
            GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
 
999
            __FILE__,
 
1000
            _function_name_,
 
1001
            __LINE__,
 
1002
            _GASL("Could not allocate enough memory")));
 
1003
        goto error_exit;
 
1004
    }
 
1005
 
 
1006
    gline_tmp->dn = parsed_dn;
 
1007
    gline_tmp->user_ids = userids;
 
1008
 
 
1009
    *gline = gline_tmp;
 
1010
  
 
1011
    goto exit;
 
1012
 
 
1013
 error_exit:
 
1014
 
 
1015
    if (parsed_dn)
 
1016
    {
 
1017
        free(parsed_dn);
 
1018
    }
 
1019
 
 
1020
    if (userids)
 
1021
    {
 
1022
        char **userids_tmp = userids;
 
1023
 
 
1024
        while (*userids_tmp != NULL)
 
1025
        {
 
1026
            free(*userids_tmp++);
 
1027
        }
 
1028
 
 
1029
        free(userids);
 
1030
    }
 
1031
 
 
1032
 exit:
 
1033
 
 
1034
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
1035
    return result;
 
1036
 
1037
/* gridmap_parse_line() */
 
1038
/* @} */
 
1039
 
 
1040
/**
 
1041
 * @name globus_i_gsi_gss_assist
 
1042
 */
 
1043
/* @{ */
 
1044
/**
 
1045
 * @ingroup globus_i_gsi_gss_assist
 
1046
 * Frees all memory allocated to a gridmap_line_t structure.
 
1047
 *
 
1048
 * @param gline
 
1049
 *        pointer to structure to be freed.
 
1050
 * 
 
1051
 * @return
 
1052
 *        void
 
1053
 */
 
1054
static
 
1055
void
 
1056
globus_i_gss_assist_gridmap_line_free(
 
1057
    globus_i_gss_assist_gridmap_line_t *                    
 
1058
                                        gline)
 
1059
{
 
1060
    static char *                       _function_name_ =
 
1061
        "globus_i_gss_assist_gridmap_line_free";
 
1062
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
1063
 
 
1064
    if (gline != NULL)
 
1065
    {
 
1066
        if (gline->dn != NULL)
 
1067
        {
 
1068
            free(gline->dn);
 
1069
        }
 
1070
        
 
1071
        if (gline->user_ids != NULL)
 
1072
        {
 
1073
            char **                           userids_tmp = gline->user_ids;
 
1074
            
 
1075
            while (*userids_tmp != NULL)
 
1076
            {
 
1077
                free(*userids_tmp++);
 
1078
            }
 
1079
            
 
1080
            free(gline->user_ids);
 
1081
        }
 
1082
        
 
1083
        free(gline);
 
1084
    }
 
1085
 
1086
/* gridmap_free_gridmap_line() */
 
1087
/* @} */
 
1088
 
 
1089
/**
 
1090
 * @name Gridmap Parse Globusid
 
1091
 */
 
1092
/* @{ */
 
1093
/**
 
1094
 * @ingroup globus_i_gsi_gss_assist
 
1095
 * Given a pointer to a string containing the globusid from the
 
1096
 * gridmap file, return a pointer to a string containing the
 
1097
 * parsed from of the id.
 
1098
 *
 
1099
 * Specifically handle backslashed characters - e.g. '\\',
 
1100
 * '\x4a' or '\37'.
 
1101
 *
 
1102
 * @param unparsed
 
1103
 *        the unparsed globusid
 
1104
 * @param pparsed
 
1105
 *        the resulting parsed string - this should be freed when
 
1106
 *        no longer needed
 
1107
 * @result
 
1108
 *        0 on success, otherwise an error object identifier is returned.
 
1109
 *        use globus_error_get to get the error object from the id.  The
 
1110
 *        resulting error object must be freed using globus_object_free
 
1111
 *        when it is no longer needed.
 
1112
 *
 
1113
 * @see globus_error_get
 
1114
 * @see globus_object_free
 
1115
 */
 
1116
static
 
1117
globus_result_t
 
1118
globus_i_gss_assist_gridmap_parse_globusid(
 
1119
    const char *                        unparsed,
 
1120
    char **                             pparsed)
 
1121
{
 
1122
    /* Is the current character escaped? (Previous char was backslash) */
 
1123
    int                                 escaped = 0;
 
1124
 
 
1125
  /* Buffer we are putting resulting name into */
 
1126
    char *                              buffer = NULL;
 
1127
 
 
1128
    /* Buffer's length in bytes */
 
1129
    int                                 buffer_len = 0;
 
1130
 
 
1131
    /* And our current position in buffer */
 
1132
    int                                 buffer_index = 0;
 
1133
 
 
1134
    /* Character we're currently looking at */
 
1135
    char                                unparsed_char;
 
1136
 
 
1137
    globus_result_t                     result = GLOBUS_SUCCESS;
 
1138
    static char *                       _function_name_ =
 
1139
        "globus_i_gss_assist_gridmap_parse_globusid";
 
1140
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
1141
 
 
1142
    /*
 
1143
     * Check input parameters for legality
 
1144
     */
 
1145
    if ((unparsed == NULL) ||
 
1146
        (pparsed == NULL))
 
1147
    {
 
1148
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
1149
            result,
 
1150
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
 
1151
            (_GASL("Arguments passed to function are NULL.")));
 
1152
        goto exit;
 
1153
    }
 
1154
 
 
1155
    buffer_len = strlen(unparsed);
 
1156
    buffer = malloc(buffer_len);
 
1157
 
 
1158
    if (buffer == NULL)
 
1159
    {
 
1160
        globus_error_put(globus_error_wrap_errno_error( 
 
1161
            GLOBUS_GSI_GSS_ASSIST_MODULE, 
 
1162
            errno, 
 
1163
            GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO, 
 
1164
            __FILE__,
 
1165
            _function_name_,
 
1166
            __LINE__,
 
1167
            _GASL("Could not allocate enough memory")));
 
1168
        goto exit;
 
1169
    }
 
1170
 
 
1171
    /*
 
1172
     * Walk through the name, parsing as we go
 
1173
     */
 
1174
    while ((unparsed_char = *(unparsed++)) != NUL)
 
1175
    {
 
1176
        /* Unescaped backslash */
 
1177
        if (strchr(ESCAPING_CHARS, unparsed_char) && !escaped)
 
1178
        {
 
1179
            escaped = 1;
 
1180
            continue;
 
1181
        }
 
1182
 
 
1183
        /* Escaped hex character - e.g. '\xfe' */
 
1184
        if ((unparsed_char == 'x') && escaped)
 
1185
        {
 
1186
            if (isxdigit(*unparsed) &&
 
1187
                isxdigit(*(unparsed + 1)))
 
1188
            {
 
1189
                /* Set unparsed_char to value represented by hex value */
 
1190
                unparsed_char =
 
1191
                    (globus_i_gss_assist_xdigit_to_value(*unparsed) << 4) +
 
1192
                    globus_i_gss_assist_xdigit_to_value(*(unparsed + 1));
 
1193
        
 
1194
                unparsed += 2;
 
1195
            }
 
1196
            /* else just fall through */
 
1197
        }
 
1198
 
 
1199
        /*
 
1200
         * Ok, we now have the character in unparsed_char to be appended
 
1201
         * to our output string.
 
1202
         *
 
1203
         * First, make sure we have enough room in our output buffer.
 
1204
         */
 
1205
 
 
1206
        if ((buffer_index + 1 /* for NUL */) >= buffer_len)
 
1207
        {
 
1208
            /* Grow buffer */
 
1209
            char *tmp_buffer;
 
1210
 
 
1211
            buffer_len *= 2;
 
1212
 
 
1213
            tmp_buffer = realloc(buffer, buffer_len);
 
1214
 
 
1215
            if (tmp_buffer == NULL)
 
1216
            {
 
1217
                free(buffer);
 
1218
                globus_error_put(globus_error_wrap_errno_error(
 
1219
                    GLOBUS_GSI_GSS_ASSIST_MODULE,
 
1220
                    errno,
 
1221
                    GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
 
1222
                    __FILE__,
 
1223
                    _function_name_,
 
1224
                    __LINE__,
 
1225
                    _GASL("Could not allocate enough memory")));
 
1226
                goto exit;
 
1227
            }
 
1228
            
 
1229
            buffer = tmp_buffer;
 
1230
        }
 
1231
        
 
1232
        buffer[buffer_index++] = unparsed_char;
 
1233
        buffer[buffer_index] = NUL;
 
1234
 
 
1235
        escaped = 0;
 
1236
    }
 
1237
    
 
1238
    /* XXX What if escaped == 1 here? */
 
1239
    /* Success */
 
1240
    
 
1241
    *pparsed = buffer;
 
1242
    
 
1243
 exit:
 
1244
    
 
1245
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
1246
    return result;
 
1247
 
1248
/* gridmap_parse_globusid() */
 
1249
/* @} */
 
1250
 
 
1251
/**
 
1252
 * @name Hexadecimal Digit to Integer
 
1253
 */
 
1254
/* @{ */
 
1255
/**
 
1256
 * @ingroup globus_i_gsi_gss_assist
 
1257
 * Convert an ascii character representing a hexadecimal digit
 
1258
 * into an integer.
 
1259
 *
 
1260
 * @param xdigit
 
1261
 *        character contianing the hexidecimal digit
 
1262
 *
 
1263
 * @return
 
1264
 *        the value in the xdigit, or -1 if error
 
1265
 */
 
1266
static int
 
1267
globus_i_gss_assist_xdigit_to_value(
 
1268
    char                                xdigit)
 
1269
{
 
1270
    if ((xdigit >= '0') && (xdigit <= '9'))
 
1271
        return (xdigit - '0');
 
1272
 
 
1273
    if ((xdigit >= 'a') && (xdigit <= 'f'))
 
1274
        return (xdigit - 'a' + 0xa);
 
1275
 
 
1276
    if ((xdigit >= 'A') && (xdigit <= 'F'))
 
1277
        return (xdigit - 'A' + 0xa);
 
1278
 
 
1279
    /* Illegal digit */
 
1280
    return -1;
 
1281
 
1282
/* xdigit_to_value() */
 
1283
/* @} */
 
1284
 
 
1285
#endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */
 
1286
 
 
1287
 
 
1288
/**
 
1289
 * @ingroup globus_i_gsi_gss_assist
 
1290
 * Look up all globus ids associated with a given user id.
 
1291
 *
 
1292
 * @param username
 
1293
 *        The local username on which we are preforming the lookup.
 
1294
 *
 
1295
 * @param dns
 
1296
 *        a pointer to an array of strings.  On entrance it should be
 
1297
 *        unitialized.  Upon return from this function it will point
 
1298
 *        to an array of strings.  The user should use the macro
 
1299
 *        GlobusGssAssistFreeDNArray to clean up this memory.
 
1300
 *
 
1301
 * @param dn_count
 
1302
 *        The number of globus_ids returned in dns.
 
1303
 *
 
1304
 * @return
 
1305
 *        the value in the xdigit, or -1 if error
 
1306
 */
 
1307
globus_result_t
 
1308
globus_gss_assist_lookup_all_globusid(
 
1309
    char *                                      username,
 
1310
    char **                                     dns[],
 
1311
    int *                                       dn_count)
 
1312
{
 
1313
    char                                        line[1024];
 
1314
    int                                         max_ndx = 512;
 
1315
    int                                         ndx = 0;
 
1316
    char **                                     l_dns;
 
1317
    globus_i_gss_assist_gridmap_line_t *        gline;
 
1318
    char *                                      gridmap_filename = NULL;
 
1319
    globus_result_t                             res = GLOBUS_SUCCESS;
 
1320
    FILE *                                      gmap_stream = NULL;
 
1321
    static char *                       _function_name_ =
 
1322
        "globus_gss_assist_lookup_all_globusid";
 
1323
 
 
1324
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
 
1325
 
 
1326
    /* Check arguments */
 
1327
    if(dns == NULL ||
 
1328
       username == NULL ||
 
1329
       dn_count == NULL)
 
1330
    {
 
1331
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
1332
            res,
 
1333
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
 
1334
            (_GASL("An argument passed to function is NULL.")));
 
1335
 
 
1336
        goto exit;
 
1337
    }
 
1338
 
 
1339
    res = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
 
1340
    if(res != GLOBUS_SUCCESS)
 
1341
    {
 
1342
        gridmap_filename = NULL;
 
1343
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1344
            res,
 
1345
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
 
1346
 
 
1347
        goto exit;
 
1348
    }
 
1349
 
 
1350
    gmap_stream = fopen(gridmap_filename, "r");
 
1351
 
 
1352
    if (gmap_stream == NULL)
 
1353
    {
 
1354
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
1355
            res,
 
1356
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
 
1357
            (_GASL("Couldn't open gridmap file: %s for reading."),
 
1358
             gridmap_filename));
 
1359
 
 
1360
        goto exit;
 
1361
    }
 
1362
 
 
1363
    ndx = 0;
 
1364
    l_dns = (char **)globus_malloc(sizeof(char *) * max_ndx);
 
1365
 
 
1366
    while(fgets(line, sizeof(line), gmap_stream) != NULL)
 
1367
    {
 
1368
        res = globus_i_gss_assist_gridmap_parse_line(line, &gline);
 
1369
 
 
1370
        if(res == GLOBUS_SUCCESS &&
 
1371
           gline != NULL &&
 
1372
           gline->user_ids != NULL &&
 
1373
           gline->user_ids[0] != NULL)
 
1374
        {
 
1375
            if(strcmp(gline->user_ids[0], username) == 0)
 
1376
            {
 
1377
                l_dns[ndx] = strdup(gline->dn);
 
1378
                ndx++;
 
1379
                if(ndx >= max_ndx)
 
1380
                {
 
1381
                    max_ndx *= 2;
 
1382
                    l_dns = (char **)globus_libc_realloc(l_dns,
 
1383
                                         sizeof(char *) * max_ndx);
 
1384
                }
 
1385
            }
 
1386
        }
 
1387
    }
 
1388
    l_dns[ndx] = NULL;
 
1389
    *dns = l_dns;
 
1390
    *dn_count = ndx;
 
1391
 
 
1392
    fclose(gmap_stream);
 
1393
    gmap_stream = NULL;
 
1394
 
 
1395
 exit:
 
1396
 
 
1397
    if(gridmap_filename != NULL)
 
1398
    {
 
1399
        free(gridmap_filename);
 
1400
    }
 
1401
 
 
1402
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
1403
 
 
1404
    return res;
 
1405
}
 
1406
/* globus_gss_assist_lookup_all_globusid() */
 
1407
 
 
1408
 
 
1409
globus_result_t
 
1410
globus_gss_assist_map_and_authorize(
 
1411
    gss_ctx_id_t                        context,
 
1412
    char *                              service,
 
1413
    char *                              desired_identity,
 
1414
    char *                              identity_buffer,
 
1415
    unsigned int                        identity_buffer_length)
 
1416
{
 
1417
    globus_object_t *                   error;
 
1418
    globus_result_t                     result = GLOBUS_SUCCESS;
 
1419
    static globus_bool_t                initialized = GLOBUS_FALSE;
 
1420
    static globus_callout_handle_t      authz_handle = NULL;
 
1421
 
 
1422
    static char *                       _function_name_ =
 
1423
        "globus_gss_assist_map_and_authorize";
 
1424
    
 
1425
    globus_mutex_lock(&globus_i_gsi_gss_assist_mutex);
 
1426
    {
 
1427
        if(initialized == GLOBUS_FALSE)
 
1428
        {
 
1429
            char *                      filename;
 
1430
            result = GLOBUS_GSI_SYSCONFIG_GET_AUTHZ_CONF_FILENAME(&filename);
 
1431
            
 
1432
            if(result != GLOBUS_SUCCESS)
 
1433
            {
 
1434
                error = globus_error_get(result);
 
1435
        
 
1436
                if(globus_error_match(
 
1437
                       error,
 
1438
                       GLOBUS_GSI_SYSCONFIG_MODULE,
 
1439
                       GLOBUS_GSI_SYSCONFIG_ERROR_GETTING_AUTHZ_FILENAME)
 
1440
                   == GLOBUS_TRUE)
 
1441
                {
 
1442
                    globus_object_free(error);
 
1443
                }
 
1444
                else
 
1445
                {
 
1446
                    result = globus_error_put(error);
 
1447
                    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
 
1448
                    return result;
 
1449
                }
 
1450
            }
 
1451
            else
 
1452
            {
 
1453
                result = globus_callout_handle_init(&authz_handle);
 
1454
            
 
1455
                if(result != GLOBUS_SUCCESS)
 
1456
                {
 
1457
                    free(filename);
 
1458
                    GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1459
                        result,
 
1460
                        GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_CALLOUT_CONFIG);
 
1461
                    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
 
1462
                    return result;
 
1463
                }
 
1464
            
 
1465
                result = globus_callout_read_config(authz_handle, filename);
 
1466
 
 
1467
                free(filename);
 
1468
            
 
1469
                if(result != GLOBUS_SUCCESS)
 
1470
                {
 
1471
                    GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1472
                        result,
 
1473
                        GLOBUS_GSI_GSS_ASSIST_ERROR_INITIALIZING_CALLOUT_HANDLE);
 
1474
                    globus_callout_handle_destroy(authz_handle);
 
1475
                    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
 
1476
                    return result;
 
1477
                }
 
1478
            }
 
1479
            initialized = GLOBUS_TRUE;
 
1480
        }
 
1481
    }
 
1482
    globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
 
1483
 
 
1484
    
 
1485
    if(authz_handle == NULL)
 
1486
    {
 
1487
        return globus_l_gss_assist_gridmap_lookup(
 
1488
            context,
 
1489
            service,
 
1490
            desired_identity,
 
1491
            identity_buffer,
 
1492
            identity_buffer_length);
 
1493
    }
 
1494
    else
 
1495
    {            
 
1496
        result = globus_callout_call_type(authz_handle,
 
1497
                                          GLOBUS_GENERIC_MAPPING_TYPE,
 
1498
                                          context,
 
1499
                                          service,
 
1500
                                          desired_identity,
 
1501
                                          identity_buffer,
 
1502
                                          identity_buffer_length);
 
1503
        
 
1504
        if(result != GLOBUS_SUCCESS)
 
1505
        {
 
1506
            error = globus_error_get(result);
 
1507
            
 
1508
            if(globus_error_match(
 
1509
                   error,
 
1510
                   GLOBUS_CALLOUT_MODULE,
 
1511
                   GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED)
 
1512
               == GLOBUS_TRUE)
 
1513
            {
 
1514
                globus_object_free(error);
 
1515
                result = globus_l_gss_assist_gridmap_lookup(
 
1516
                    context,
 
1517
                    service,
 
1518
                    desired_identity,
 
1519
                    identity_buffer,
 
1520
                    identity_buffer_length);
 
1521
                goto error;
 
1522
            }
 
1523
            else
 
1524
            {
 
1525
                result = globus_error_put(error);
 
1526
                GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1527
                    result,
 
1528
                    GLOBUS_GSI_GSS_ASSIST_CALLOUT_ERROR);
 
1529
                goto error;
 
1530
            }
 
1531
        }
 
1532
 
 
1533
        result = globus_callout_call_type(authz_handle,
 
1534
                                          GLOBUS_GENERIC_AUTHZ_TYPE,
 
1535
                                          context,
 
1536
                                          service);        
 
1537
        if(result != GLOBUS_SUCCESS)
 
1538
        {
 
1539
            error = globus_error_get(result);
 
1540
            
 
1541
            if(globus_error_match(
 
1542
                   error,
 
1543
                   GLOBUS_CALLOUT_MODULE,
 
1544
                   GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED)
 
1545
               == GLOBUS_FALSE)
 
1546
            {
 
1547
                result = globus_error_put(error);
 
1548
                GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1549
                    result,
 
1550
                    GLOBUS_GSI_GSS_ASSIST_CALLOUT_ERROR);
 
1551
                goto error;
 
1552
            }
 
1553
            else
 
1554
            {
 
1555
                result = GLOBUS_SUCCESS;
 
1556
            }
 
1557
 
 
1558
            globus_object_free(error);
 
1559
        }
 
1560
    }
 
1561
    
 
1562
 
 
1563
 error:
 
1564
    return result;
 
1565
}
 
1566
/* globus_gss_assist_map_and_authorize */
 
1567
 
 
1568
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
 
1569
static
 
1570
globus_result_t
 
1571
globus_l_gss_assist_gridmap_lookup(
 
1572
    gss_ctx_id_t                        context,
 
1573
    char *                              service,
 
1574
    char *                              desired_identity,
 
1575
    char *                              identity_buffer,
 
1576
    unsigned int                        identity_buffer_length)
 
1577
{
 
1578
    gss_name_t                          peer;
 
1579
    gss_buffer_desc                     peer_name_buffer;
 
1580
    OM_uint32                           major_status;
 
1581
    OM_uint32                           minor_status;
 
1582
    int                                 initiator;
 
1583
    globus_result_t                     result = GLOBUS_SUCCESS;
 
1584
    int                                 rc;
 
1585
    char *                              local_identity;
 
1586
    static char *                       _function_name_ =
 
1587
        "globus_l_gss_assist_gridmap_lookup";
 
1588
    
 
1589
    major_status = gss_inquire_context(&minor_status,
 
1590
                                       context,
 
1591
                                       GLOBUS_NULL,
 
1592
                                       GLOBUS_NULL,
 
1593
                                       GLOBUS_NULL,
 
1594
                                       GLOBUS_NULL,
 
1595
                                       GLOBUS_NULL,
 
1596
                                       &initiator,
 
1597
                                       GLOBUS_NULL);
 
1598
 
 
1599
    if(GSS_ERROR(major_status))
 
1600
    {
 
1601
        result =  minor_status;
 
1602
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1603
            result,
 
1604
            GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
 
1605
        goto error;
 
1606
    }
 
1607
 
 
1608
    major_status = gss_inquire_context(&minor_status,
 
1609
                                       context,
 
1610
                                       initiator ? GLOBUS_NULL : &peer,
 
1611
                                       initiator ? &peer : GLOBUS_NULL,
 
1612
                                       GLOBUS_NULL,
 
1613
                                       GLOBUS_NULL,
 
1614
                                       GLOBUS_NULL,
 
1615
                                       GLOBUS_NULL,
 
1616
                                       GLOBUS_NULL);
 
1617
 
 
1618
    if(GSS_ERROR(major_status))
 
1619
    {
 
1620
        result =  minor_status;
 
1621
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1622
            result,
 
1623
            GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
 
1624
        goto error;
 
1625
    }
 
1626
    
 
1627
    major_status = gss_display_name(&minor_status,
 
1628
                                    peer,
 
1629
                                    &peer_name_buffer,
 
1630
                                    GLOBUS_NULL);
 
1631
    if(GSS_ERROR(major_status))
 
1632
    {
 
1633
        result =  minor_status;
 
1634
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
 
1635
            result,
 
1636
            GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
 
1637
        gss_release_name(&minor_status, &peer);
 
1638
        goto error;
 
1639
    }
 
1640
 
 
1641
    gss_release_name(&minor_status, &peer);        
 
1642
    
 
1643
    if(desired_identity == NULL)
 
1644
    {
 
1645
        rc = globus_gss_assist_gridmap(
 
1646
            peer_name_buffer.value, 
 
1647
            &local_identity);
 
1648
        
 
1649
        if(rc != 0)
 
1650
        {
 
1651
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
1652
                result,
 
1653
                GLOBUS_GSI_GSS_ASSIST_GRIDMAP_LOOKUP_FAILED,
 
1654
                (_GASL("Could not map %s\n"), peer_name_buffer.value));
 
1655
            gss_release_buffer(&minor_status, &peer_name_buffer);
 
1656
            goto error;
 
1657
        }
 
1658
 
 
1659
        if(strlen(local_identity) + 1 > identity_buffer_length)
 
1660
        {
 
1661
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
1662
                result,
 
1663
                GLOBUS_GSI_GSS_ASSIST_BUFFER_TOO_SMALL,
 
1664
                (_GASL("Local identity length: %d Buffer length: %d\n"),
 
1665
                 strlen(local_identity), identity_buffer_length));
 
1666
        }
 
1667
        else
 
1668
        {
 
1669
            strcpy(identity_buffer, local_identity);
 
1670
        }
 
1671
        free(local_identity);
 
1672
    }
 
1673
    else
 
1674
    {
 
1675
        rc = globus_gss_assist_userok(peer_name_buffer.value,
 
1676
                                      desired_identity);
 
1677
        if(rc != 0)
 
1678
        {
 
1679
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
1680
                result,
 
1681
                GLOBUS_GSI_GSS_ASSIST_GRIDMAP_LOOKUP_FAILED,
 
1682
                (_GASL("Could not map %s to %s\n"),
 
1683
                 peer_name_buffer.value,
 
1684
                 desired_identity));
 
1685
            goto error;
 
1686
        }
 
1687
 
 
1688
        if(strlen(desired_identity) + 1 > identity_buffer_length)
 
1689
        {
 
1690
            GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
 
1691
                result,
 
1692
                GLOBUS_GSI_GSS_ASSIST_BUFFER_TOO_SMALL,
 
1693
                (_GASL("Desired identity length: %d Buffer length: %d\n"),
 
1694
                 strlen(desired_identity), identity_buffer_length));
 
1695
        }
 
1696
        else
 
1697
        {
 
1698
            strcpy(identity_buffer, desired_identity);
 
1699
        }
 
1700
    }
 
1701
 
 
1702
    gss_release_buffer(&minor_status, &peer_name_buffer);
 
1703
 
 
1704
 error:
 
1705
    return result;
 
1706
}
 
1707
#endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */