2
* Copyright 1999-2006 University of Chicago
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
20
* GSSAPI module activation code
22
* $RCSfile: gridmap.c,v $
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"
35
typedef struct _gridmap_line_s {
38
} globus_i_gss_assist_gridmap_line_t;
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 ","
47
* Characters that terminate a user id in the gridmap file. This
48
* is a combination of whitespace and seperators.
50
#define USERID_TERMINATOR_CHARS USERID_SEP_CHARS WHITESPACE_CHARS
56
#define GLOBUS_GENERIC_MAPPING_TYPE "globus_mapping"
57
#define GLOBUS_GENERIC_AUTHZ_TYPE "globus_authorization"
60
* Number of user id slots to allocate at a time
61
* Arbitraty value, but must be >= 2.
63
#define USERID_CHUNK_SIZE 4
65
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
69
globus_i_gss_assist_gridmap_find_dn(
70
const char * const dn,
71
globus_i_gss_assist_gridmap_line_t **
76
globus_i_gss_assist_gridmap_find_local_user(
77
const char * const local_user,
78
globus_i_gss_assist_gridmap_line_t **
83
globus_i_gss_assist_gridmap_parse_line(
85
globus_i_gss_assist_gridmap_line_t **
89
globus_i_gss_assist_gridmap_line_free(
90
globus_i_gss_assist_gridmap_line_t *
95
globus_i_gss_assist_gridmap_parse_globusid(
100
globus_i_gss_assist_xdigit_to_value(
105
globus_l_gss_assist_gridmap_lookup(
106
gss_ctx_id_t context,
108
char * desired_identity,
109
char * identity_buffer,
110
unsigned int identity_buffer_length);
114
globus_l_gss_assist_line_length(
122
/******************************************************************************
123
Start of gridmapdir functions
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)
130
******************************************************************************/
136
#include <sys/stat.h>
138
#include <sys/types.h>
140
/******************************************************************************
141
Function: gridmapdir_otherlink
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)
148
firstlink, the filename of the link we already know
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)
154
******************************************************************************/
156
*gridmapdir_otherlink(char * firstlink)
159
char *firstlinkpath, *otherlinkdup, *otherlinkpath,
161
struct dirent *gridmapdirentry;
162
DIR *gridmapdirstream;
166
gridmapdir = getenv("GRIDMAPDIR");
167
if (gridmapdir == NULL) return NULL;
169
firstlinkpath = malloc(strlen(gridmapdir) + 2 + strlen(firstlink));
170
sprintf(firstlinkpath, "%s/%s", gridmapdir, firstlink);
171
ret = stat(firstlinkpath, &statbuf);
173
if (ret != 0) return NULL;
174
if (statbuf.st_nlink != 2) return NULL;
176
firstinode = statbuf.st_ino; /* save for comparisons */
178
gridmapdirstream = opendir(gridmapdir);
180
if (gridmapdirstream != NULL)
182
while ((gridmapdirentry = readdir(gridmapdirstream)) != NULL)
184
if (strcmp(gridmapdirentry->d_name, firstlink) == 0) continue;
186
otherlinkpath = malloc(strlen(gridmapdir) + 2 +
187
strlen(gridmapdirentry->d_name));
188
sprintf(otherlinkpath, "%s/%s", gridmapdir,
189
gridmapdirentry->d_name);
191
ret = stat(otherlinkpath, &statbuf);
192
if ((ret == 0) && (statbuf.st_ino == firstinode))
194
utime(otherlinkpath, (struct utimbuf *) NULL);
196
otherlinkdup = strdup(gridmapdirentry->d_name);
197
closedir(gridmapdirstream);
200
else free(otherlinkpath);
203
closedir(gridmapdirstream);
209
/******************************************************************************
210
Function: gridmapdir_urlencode
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.
219
rawstring, the string to be converted
222
a pointer to the encoded string or NULL if the malloc failed
224
******************************************************************************/
226
*gridmapdir_urlencode(char * rawstring)
228
int encodedchar = 0, rawchar = 0;
229
char * encodedstring;
231
encodedstring = (char *) malloc(3 * strlen(rawstring) + 1);
233
if (encodedstring == NULL) return (char *) NULL;
235
while (rawstring[rawchar] != '\0')
237
if (isalnum(rawstring[rawchar]))
239
encodedstring[encodedchar] = tolower(rawstring[rawchar]);
245
sprintf(&encodedstring[encodedchar], "%%%02x",
248
encodedchar = encodedchar + 3;
252
encodedstring[encodedchar] = '\0';
254
return encodedstring;
257
/******************************************************************************
258
Function: gridmapdir_newlease
260
Search for an unleased local username to give to the globus user
261
corresponding to encodedfilename, and then lease it.
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")
270
******************************************************************************/
273
gridmapdir_newlease(char * encodedglobusidp,
274
char * usernameprefix)
277
char *userfilename, *encodedfilename, *gridmapdir;
278
struct dirent *gridmapdirentry;
279
DIR *gridmapdirstream;
282
gridmapdir = getenv("GRIDMAPDIR");
283
if (gridmapdir == NULL) return;
285
encodedfilename = malloc(strlen(gridmapdir) + (size_t) 2 +
286
strlen(encodedglobusidp));
287
sprintf(encodedfilename, "%s/%s", gridmapdir, encodedglobusidp);
289
gridmapdirstream = opendir(gridmapdir);
291
while ((gridmapdirentry = readdir(gridmapdirstream)) != NULL)
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;
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);
306
if (statbuf.st_nlink == 1) /* this one isnt leased yet */
308
ret = link(userfilename, encodedfilename);
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);
320
stat(encodedfilename, &statbuf);
321
if (statbuf.st_nlink > 2)
323
/* two globusIDs have grabbed the same username: back off */
324
unlink(encodedfilename);
328
closedir(gridmapdirstream);
329
free(encodedfilename);
330
return; /* link worked ok, so return */
332
else free(userfilename); /* already in use, try next one */
335
closedir(gridmapdirstream);
336
free(encodedfilename);
337
return; /* no unleased names left: give up */
340
/******************************************************************************
341
Function: gridmapdir_userid
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)
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.
360
******************************************************************************/
363
gridmapdir_userid(char * globusidp,
364
char * usernameprefix,
367
char *encodedglobusidp;
369
if (getenv("GRIDMAPDIR") == NULL) return 1; /* GRIDMAPDIR defined? */
371
if (globusidp[0] != '/') return 1; /* must be a proper subject DN */
373
encodedglobusidp = gridmapdir_urlencode(globusidp);
375
*useridp = gridmapdir_otherlink(encodedglobusidp);
377
if (*useridp == NULL) /* maybe no lease yet */
379
gridmapdir_newlease(encodedglobusidp, usernameprefix);
380
/* try making a lease */
382
*useridp = gridmapdir_otherlink(encodedglobusidp);
383
/* check if there is a now a lease - possibly made by someone else */
385
if (*useridp == NULL)
387
free(encodedglobusidp);
388
return 1; /* still no good */
392
free(encodedglobusidp);
396
/******************************************************************************
397
Function: gridmapdir_globusid
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
405
globus client name who requested authentication
406
*userid returned userid name for local system.
413
******************************************************************************/
416
gridmapdir_globusid(char * useridp,
419
int encodedptr = 0, decodedptr = 0;
420
char *encodedglobusidp;
422
if (useridp == NULL || globusidp == NULL)
427
if (useridp[0] == '/') return 1; /* must not be a subject DN */
429
encodedglobusidp = gridmapdir_otherlink(useridp);
431
if (encodedglobusidp == NULL) return 1; /* not leased */
433
*globusidp = malloc(strlen(encodedglobusidp));
435
while (encodedglobusidp[encodedptr] != '\0')
437
if (encodedglobusidp[encodedptr] != '%')
439
(*globusidp)[decodedptr] = encodedglobusidp[encodedptr];
443
else /* must be a %HH encoded character */
445
/* even paranoids have enemies ... */
446
if (encodedglobusidp[encodedptr+1] == '\0') break;
447
if (encodedglobusidp[encodedptr+2] == '\0') break;
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]);
453
encodedptr = encodedptr + 3;
458
free(encodedglobusidp);
459
(*globusidp)[decodedptr] = '\0';
463
/******************************************************************************
464
Function: gridmapdir_userok
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)
473
globus client name who requested authentication
477
0 on success (authorization allowed)
478
!=0 on failure or authorization denied
480
******************************************************************************/
483
gridmapdir_userok(char * globusidp,
486
char *encodedglobusidp, *leasedname;
488
if (globusidp[0] != '/') return 1; /* must be a proper subject DN */
490
encodedglobusidp = gridmapdir_urlencode(globusidp);
491
leasedname = gridmapdir_otherlink(encodedglobusidp);
492
free(encodedglobusidp);
494
if (leasedname == NULL) return 1;
496
if (strcmp(userid, leasedname) == 0)
508
/******************************************************************************
509
End of gridmapdir functions
510
******************************************************************************/
513
* @brief Look up the default mapping for a Grid identity in a gridmap file
514
* @ingroup globus_gsi_gss_assist
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
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.
528
* The GSSAPI name string of the identity who requested authorization
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.
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
539
* @retval GLOBUS_SUCCESS
545
globus_gss_assist_gridmap(
549
globus_result_t result = GLOBUS_SUCCESS;
550
globus_i_gss_assist_gridmap_line_t *
552
char *usernameprefix;
555
static char * _function_name_ =
556
"globus_gss_assist_gridmap";
557
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
559
/* Check arguments */
560
if ((globusidp == NULL) || (useridp == NULL))
562
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
564
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
565
(_GASL("Params passed to function are NULL")));
571
result = globus_i_gss_assist_gridmap_find_dn(globusidp, &gline);
572
if(result != GLOBUS_SUCCESS)
574
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
576
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
582
if ((gline->user_ids == NULL) ||
583
(gline->user_ids[0] == NULL))
586
* If we get here then something in this code is broken
587
* or the gridmap file is badly formatted or, most likely,
590
GLOBUS_GSI_GSS_ASSIST_ERROR_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);
598
/* First user id is default */
599
*useridp = strdup(gline->user_ids[0]);
601
globus_i_gss_assist_gridmap_line_free(gline);
603
if (*useridp == NULL)
605
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
607
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
608
(_GASL("Duplicate string operation failed")));
612
if ((*useridp)[0] == '.') /* need to use gridmapdir */
614
usernameprefix = strdup(&((*useridp)[1]));
615
free(*useridp); *useridp = NULL;
616
ret = gridmapdir_userid(globusidp, usernameprefix, useridp);
617
free(usernameprefix);
624
char * gridmap_filename = NULL;
626
GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
628
/* No entry found in gridmap file for this user */
629
GLOBUS_GSI_GSS_ASSIST_ERROR_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."),
635
gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
637
free(gridmap_filename);
643
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
644
if(result == GLOBUS_SUCCESS)
650
globus_object_t * error_obj;
651
error_obj = globus_error_get(result);
652
globus_object_free(error_obj);
657
/* globus_gss_assist_gridmap() */
660
* @brief Gridmap entry existence check
661
* @ingroup globus_gsi_gss_assist
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
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.
674
* The GSSAPI name string of the identity who requested authorization
676
* The local account name that access is sought for.
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.
682
* @retval GLOBUS_SUCCESS
688
globus_gss_assist_userok(
692
char * gridmap_filename = NULL;
693
globus_result_t result = GLOBUS_SUCCESS;
694
globus_i_gss_assist_gridmap_line_t *
697
static char * _function_name_ =
698
"globus_gss_assist_userok";
699
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
701
/* Check arguments */
702
if ((globusid == NULL) ||
705
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
707
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
708
(_GASL("Arguments passed to function are NULL")));
712
result = globus_i_gss_assist_gridmap_find_dn(globusid, &gline);
713
if(result != GLOBUS_SUCCESS)
715
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
717
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
723
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
725
GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
726
(_GASL("The DN: %s does not map to the username: %s"),
731
if (gline->user_ids == NULL)
733
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
735
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
736
(_GASL("The gridmap is malformated. No user id's could be be found.")));
740
if (*((gline->user_ids)[0]) == '.') /* try using gridmapdir */
742
globus_i_gss_assist_gridmap_line_free(gline);
743
return gridmapdir_userok(globusid, userid);
746
for (useridp = gline->user_ids; *useridp != NULL; useridp++)
748
if (strcmp(*useridp, userid) == 0)
754
GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
755
GLOBUS_GSI_GSS_ASSIST_ERROR_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 "
762
gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
763
free(gridmap_filename);
769
globus_i_gss_assist_gridmap_line_free(gline);
772
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
773
if(result == GLOBUS_SUCCESS)
779
globus_object_t * error_obj;
780
error_obj = globus_error_get(result);
781
globus_object_free(error_obj);
786
/* globus_gss_assist_userok() */
789
* @brief Look up the default Grid identity associated with a local user name
790
* @ingroup globus_gsi_gss_assist
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.
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.
807
* The local username to find a Grid ID for
809
* A Grid ID that maps from the local_user.
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.
817
* @retval GLOBUS_SUCCESS
823
globus_gss_assist_map_local_user(
827
char * gridmap_filename = NULL;
828
globus_result_t result = GLOBUS_SUCCESS;
829
globus_i_gss_assist_gridmap_line_t *
831
static char * _function_name_ =
832
"globus_gss_assist_map_local_user";
833
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
835
/* Check arguments */
836
if ((local_user == NULL) ||
839
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
841
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
842
(_GASL("Arguments passed to the function are NULL.")));
848
result = globus_i_gss_assist_gridmap_find_local_user(local_user, &gline);
849
if(result != GLOBUS_SUCCESS)
852
* We failed to open the gridmap file.
854
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
856
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
862
if (gline->dn == NULL)
864
GLOBUS_GSI_GSS_ASSIST_ERROR_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.")));
872
/* First user id is default */
873
*globusidp = strdup(gline->dn);
875
if (*globusidp == NULL)
877
/* strdup() failed */
878
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
880
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
881
(_GASL("The string duplication operation failed.")));
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(
891
GLOBUS_GSI_GSS_ASSIST_ERROR_IN_GRIDMAP_NO_USER_ENTRY,
892
(_GASL("No DN entry found for user: %s in gridmap file: %s"),
894
gridmap_filename != NULL ? gridmap_filename : "(NULL)"));
895
free(gridmap_filename);
903
globus_i_gss_assist_gridmap_line_free(gline);
906
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
907
if(result == GLOBUS_SUCCESS)
913
globus_object_t * error_obj;
914
error_obj = globus_error_get(result);
915
globus_object_free(error_obj);
917
/* try with gridmapdir before giving up completely */
918
return gridmapdir_globusid(local_user, globusidp);
921
/* globus_gss_assist_map_local_user() */
923
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
926
* @name Gridmap Find DN
930
* @ingroup globus_i_gsi_gss_assist
931
* Locate the entry for the given DN in the default gridmap file
934
* the distinguished name to search for
936
* gives the line information
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.
944
* @see globus_error_get
945
* @see globus_object_free
949
globus_i_gss_assist_gridmap_find_dn(
950
const char * const dn,
951
globus_i_gss_assist_gridmap_line_t **
954
char * gridmap_filename = NULL;
955
globus_result_t result = GLOBUS_SUCCESS;
956
char * open_mode = "r";
957
FILE * gmap_stream = NULL;
959
globus_i_gss_assist_gridmap_line_t *
961
static char * _function_name_ =
962
"globus_i_gss_assist_gridmap_find_dn";
963
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
966
/* Check arguments */
969
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
971
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
972
(_GASL("The DN passed to function is NULL.")));
976
result = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
977
if(result != GLOBUS_SUCCESS)
979
gridmap_filename = NULL;
980
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
982
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
986
gmap_stream = fopen(gridmap_filename, open_mode);
988
if (gmap_stream == NULL)
990
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
992
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
993
(_GASL("Couldn't open gridmap file: %s for reading."),
998
free(gridmap_filename);
999
gridmap_filename = NULL;
1006
result = globus_l_gss_assist_line_length(gmap_stream, &line_len);
1007
if (result != GLOBUS_SUCCESS || line_len == 0)
1012
line = malloc(++line_len);
1015
result = globus_error_put(globus_error_wrap_errno_error(
1016
GLOBUS_GSI_GSS_ASSIST_MODULE,
1018
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1022
_GASL("Could not allocate enough memory")));
1026
if (fgets(line, line_len, gmap_stream) == NULL)
1029
break; /* EOF or error */
1032
result = globus_i_gss_assist_gridmap_parse_line(line, &gline_tmp);
1033
if (result != GLOBUS_SUCCESS)
1035
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1037
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1039
continue; /* Parse error */
1042
if ((gline_tmp != NULL) &&
1043
(globus_i_gsi_cert_utils_dn_cmp(dn, gline_tmp->dn) == 0))
1049
globus_i_gss_assist_gridmap_line_free(gline_tmp);
1054
fclose(gmap_stream);
1068
if (gridmap_filename != NULL)
1070
free(gridmap_filename);
1073
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1076
/* gridmap_find_dn() */
1080
* @name Find Local User
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.
1090
* the name to search for
1092
* the resulting gridmap_line_t contianing the user and DN information
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.
1100
* @see globus_error_get
1101
* @see globus_object_free
1105
globus_i_gss_assist_gridmap_find_local_user(
1106
const char * const local_user,
1107
globus_i_gss_assist_gridmap_line_t **
1110
char * gridmap_filename = NULL;
1111
char * open_mode = "r";
1112
FILE * gmap_stream = NULL;
1114
globus_i_gss_assist_gridmap_line_t *
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;
1123
/* Check arguments */
1124
if (local_user == NULL)
1126
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1128
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
1129
(_GASL("Arguments passed to function are NULL.")));
1133
result = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
1134
if(result != GLOBUS_SUCCESS)
1136
gridmap_filename = NULL;
1137
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1139
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1143
gmap_stream = fopen(gridmap_filename, open_mode);
1145
if (gmap_stream == NULL)
1147
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1149
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
1150
(_GASL("Can't open the file: %s"), gridmap_filename));
1160
result = globus_l_gss_assist_line_length(gmap_stream, &line_len);
1161
if (result != GLOBUS_SUCCESS || line_len == 0)
1166
line = malloc(++line_len);
1169
result = globus_error_put(globus_error_wrap_errno_error(
1170
GLOBUS_GSI_GSS_ASSIST_MODULE,
1172
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1176
_GASL("Could not allocate enough memory")));
1180
if (fgets(line, line_len, gmap_stream) == NULL)
1183
break; /* EOF or error */
1186
save_line = strdup(line);
1188
result = globus_i_gss_assist_gridmap_parse_line(line, &gline_tmp);
1189
if(result != GLOBUS_SUCCESS)
1193
continue; /* Parse error */
1196
if (gline_tmp == NULL)
1204
for(useridp = gline_tmp->user_ids;
1205
useridp != NULL && *useridp != NULL && !found;
1208
if(strcmp(local_user, *useridp) == 0)
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])
1217
else if(nondefault_line == NULL)
1219
nondefault_line = strdup(save_line);
1225
globus_i_gss_assist_gridmap_line_free(gline_tmp);
1231
if(nondefault_line != NULL)
1233
result = globus_i_gss_assist_gridmap_parse_line(
1234
nondefault_line, &gline_tmp);
1235
free(nondefault_line);
1236
if(result != GLOBUS_SUCCESS)
1243
fclose(gmap_stream);
1253
if (gridmap_filename)
1255
free(gridmap_filename);
1259
fclose(gmap_stream);
1261
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1264
/* gridmap_find_local_user() */
1268
* @name Gridmap Parse Line
1272
* @ingroup globus_i_gsi_gss_assist
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.
1286
* the resulting parsed gridmap line structure
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.
1294
* @see globus_error_get
1295
* @see globus_object_free
1299
globus_i_gss_assist_gridmap_parse_line(
1301
globus_i_gss_assist_gridmap_line_t **
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 *
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;
1316
/* Check arguments */
1317
if ((line == NULL) ||
1320
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1322
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
1323
(_GASL("Arguments passed to function are NULL.")));
1327
/* Skip over leading whitespace */
1328
line += strspn(line, WHITESPACE_CHARS);
1330
/* Check for comment at start of line and ignore line if present */
1331
if (strchr(COMMENT_CHARS, *line) != NULL)
1333
/* Ignore line, return NULL gline */
1338
/* Check for empty line */
1341
/* Empty line, return NULL gline. */
1347
if (strchr(QUOTING_CHARS, *line) != NULL)
1350
* Yes, skip over opening quote and look for unescaped
1351
* closing double quote
1358
/* If loop below resolves bug 4979 */
1359
if (strchr(ESCAPING_CHARS, *(dn_end - 1)))
1364
dn_end += strcspn(dn_end, QUOTING_CHARS);
1368
GLOBUS_GSI_GSS_ASSIST_ERROR_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"),
1377
/* Make sure it's not escaped */
1379
while (strchr(ESCAPING_CHARS, *(dn_end - 1)) != NULL);
1383
/* No, just find next whitespace */
1384
dn_end = line + strcspn(line, WHITESPACE_CHARS);
1388
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1390
GLOBUS_GSI_GSS_ASSIST_ERROR_INVALID_GRIDMAP_FORMAT,
1391
(_GASL("Nothing follows the DN on the line:\n%s\n"),
1397
/* NUL terminate DN and parse */
1400
result = globus_i_gss_assist_gridmap_parse_globusid(line, &parsed_dn);
1401
if(result != GLOBUS_SUCCESS)
1403
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1405
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1409
/* Skip over closing delim and any whitespace after DN */
1411
line += strspn(line, WHITESPACE_CHARS);
1413
/* Parse list of unix user ID seperated by USERID_SEP_CHARS */
1414
while (*line != NUL)
1418
/* Find end of this userid */
1419
userid_len = strcspn(line, USERID_TERMINATOR_CHARS);
1421
/* Make sure we have a slot and if not allocate it */
1422
if ((num_userids + 1 /* new entry */+ 1 /* for NULL */) > userid_slots)
1425
userid_slots += USERID_CHUNK_SIZE;
1426
userids_tmp = realloc(userids, userid_slots * sizeof(char *));
1430
result = globus_error_put(globus_error_wrap_errno_error(
1431
GLOBUS_GSI_GSS_ASSIST_MODULE,
1433
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1437
_GASL("Could not allocate enough memory")));
1441
userids = userids_tmp;
1444
userids[num_userids] = malloc(userid_len + 1 /* for NUL */);
1446
if (!userids[num_userids])
1448
result = globus_error_put(globus_error_wrap_errno_error(
1449
GLOBUS_GSI_GSS_ASSIST_MODULE,
1451
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1455
_GASL("Could not allocate enough memory")));
1459
strncpy(userids[num_userids], line, userid_len);
1460
userids[num_userids][userid_len] = NUL;
1463
userids[num_userids] = NULL;
1466
line += strspn(line, USERID_TERMINATOR_CHARS);
1469
/* Ok, build our gridmap_line_t structure */
1470
gline_tmp = malloc(sizeof(*gline_tmp));
1472
if (gline_tmp == NULL)
1474
result = globus_error_put(globus_error_wrap_errno_error(
1475
GLOBUS_GSI_GSS_ASSIST_MODULE,
1477
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1481
_GASL("Could not allocate enough memory")));
1485
gline_tmp->dn = parsed_dn;
1486
gline_tmp->user_ids = userids;
1501
char **userids_tmp = userids;
1503
while (*userids_tmp != NULL)
1505
free(*userids_tmp++);
1513
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1516
/* gridmap_parse_line() */
1520
* @name globus_i_gsi_gss_assist
1524
* @ingroup globus_i_gsi_gss_assist
1525
* Frees all memory allocated to a gridmap_line_t structure.
1528
* pointer to structure to be freed.
1535
globus_i_gss_assist_gridmap_line_free(
1536
globus_i_gss_assist_gridmap_line_t *
1539
static char * _function_name_ =
1540
"globus_i_gss_assist_gridmap_line_free";
1541
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1545
if (gline->dn != NULL)
1550
if (gline->user_ids != NULL)
1552
char ** userids_tmp = gline->user_ids;
1554
while (*userids_tmp != NULL)
1556
free(*userids_tmp++);
1559
free(gline->user_ids);
1565
/* gridmap_free_gridmap_line() */
1569
* @name Gridmap Parse Globusid
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.
1578
* Specifically handle backslashed characters - e.g. '\\',
1582
* the unparsed globusid
1584
* the resulting parsed string - this should be freed when
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.
1592
* @see globus_error_get
1593
* @see globus_object_free
1597
globus_i_gss_assist_gridmap_parse_globusid(
1598
const char * unparsed,
1601
/* Is the current character escaped? (Previous char was backslash) */
1604
/* Buffer we are putting resulting name into */
1605
char * buffer = NULL;
1607
/* Buffer's length in bytes */
1610
/* And our current position in buffer */
1611
int buffer_index = 0;
1613
/* Character we're currently looking at */
1616
globus_result_t result = GLOBUS_SUCCESS;
1617
static char * _function_name_ =
1618
"globus_i_gss_assist_gridmap_parse_globusid";
1620
static char * hexdigit = "0123456789ABCDEF";
1622
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1625
* Check input parameters for legality
1627
if ((unparsed == NULL) ||
1630
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1632
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
1633
(_GASL("Arguments passed to function are NULL.")));
1637
buffer_len = strlen(unparsed);
1638
buffer = malloc(buffer_len);
1642
globus_error_put(globus_error_wrap_errno_error(
1643
GLOBUS_GSI_GSS_ASSIST_MODULE,
1645
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1649
_GASL("Could not allocate enough memory")));
1654
* Walk through the name, parsing as we go
1656
while ((unparsed_char = *(unparsed++)) != NUL)
1658
/* Unescaped backslash */
1659
if (strchr(ESCAPING_CHARS, unparsed_char) && !escaped)
1665
/* Escaped hex character - e.g. '\xfe' */
1666
if ((unparsed_char == 'x') && escaped)
1668
if (isxdigit(*unparsed) &&
1669
isxdigit(*(unparsed + 1)))
1671
/* Set unparsed_char to value represented by hex value */
1673
(globus_i_gss_assist_xdigit_to_value(*unparsed) << 4) +
1674
globus_i_gss_assist_xdigit_to_value(*(unparsed + 1));
1678
/* else just fall through */
1682
* Ok, we now have the character in unparsed_char to be appended
1683
* to our output string.
1685
* First, make sure we have enough room in our output buffer.
1688
while ((buffer_index + 4) >= buffer_len)
1695
tmp_buffer = realloc(buffer, buffer_len);
1697
if (tmp_buffer == NULL)
1700
globus_error_put(globus_error_wrap_errno_error(
1701
GLOBUS_GSI_GSS_ASSIST_MODULE,
1703
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1707
_GASL("Could not allocate enough memory")));
1711
buffer = tmp_buffer;
1714
if ((unparsed_char < ' ') || (unparsed_char > '~'))
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];
1723
buffer[buffer_index++] = unparsed_char;
1725
buffer[buffer_index] = NUL;
1730
/* XXX What if escaped == 1 here? */
1737
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1740
/* gridmap_parse_globusid() */
1744
* @name Hexadecimal Digit to Integer
1748
* @ingroup globus_i_gsi_gss_assist
1749
* Convert an ascii character representing a hexadecimal digit
1753
* character contianing the hexidecimal digit
1756
* the value in the xdigit, or -1 if error
1759
globus_i_gss_assist_xdigit_to_value(
1762
if ((xdigit >= '0') && (xdigit <= '9'))
1763
return (xdigit - '0');
1765
if ((xdigit >= 'a') && (xdigit <= 'f'))
1766
return (xdigit - 'a' + 0xa);
1768
if ((xdigit >= 'A') && (xdigit <= 'F'))
1769
return (xdigit - 'A' + 0xa);
1774
/* xdigit_to_value() */
1777
#endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */
1781
* @brief Look up all Grid IDs associated with a local user ID
1782
* @ingroup globus_gsi_gss_assist
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().
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.
1798
* The local username to look up in the gridmap file.
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
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.
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.
1816
* @retval GLOBUS_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
1826
globus_gss_assist_lookup_all_globusid(
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";
1844
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
1846
/* Check arguments */
1851
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1853
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_ARGUMENTS,
1854
(_GASL("An argument passed to function is NULL.")));
1859
res = GLOBUS_GSI_SYSCONFIG_GET_GRIDMAP_FILENAME(&gridmap_filename);
1860
if(res != GLOBUS_SUCCESS)
1862
gridmap_filename = NULL;
1863
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
1865
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP);
1870
gmap_stream = fopen(gridmap_filename, "r");
1872
if (gmap_stream == NULL)
1874
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
1876
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
1877
(_GASL("Couldn't open gridmap file: %s for reading."),
1884
l_dns = (char **)globus_malloc(sizeof(char *) * max_ndx);
1886
while (!feof(gmap_stream))
1888
res = globus_l_gss_assist_line_length(gmap_stream, &line_len);
1889
if (res != GLOBUS_SUCCESS || line_len == 0)
1894
line = malloc(++line_len);
1897
res = globus_error_put(globus_error_wrap_errno_error(
1898
GLOBUS_GSI_GSS_ASSIST_MODULE,
1900
GLOBUS_GSI_GSS_ASSIST_ERROR_ERRNO,
1904
_GASL("Could not allocate enough memory")));
1908
if (fgets(line, line_len, gmap_stream) == NULL)
1914
res = globus_i_gss_assist_gridmap_parse_line(line, &gline);
1916
if(res == GLOBUS_SUCCESS &&
1918
gline->user_ids != NULL)
1920
for (i = 0; gline->user_ids[i] != NULL; i++)
1922
if(strcmp(gline->user_ids[i], username) == 0)
1924
l_dns[ndx] = strdup(gline->dn);
1929
l_dns = (char **)globus_libc_realloc(l_dns,
1930
sizeof(char *) * max_ndx);
1938
globus_i_gss_assist_gridmap_line_free(gline);
1947
fclose(gmap_stream);
1952
if(gridmap_filename != NULL)
1954
free(gridmap_filename);
1957
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
1961
/* globus_gss_assist_lookup_all_globusid() */
1965
* @brief Authorize the peer of a security context to use a service
1966
* @ingroup globus_gsi_gss_assist
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.
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.
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.
1989
* Security context to inspect for peer identity information.
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
2000
* @param identity_buffer_length
2001
* Length of the @a identity_buffer array.
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.
2010
* @retval GLOBUS_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
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
2030
globus_gss_assist_map_and_authorize(
2031
gss_ctx_id_t context,
2033
char * desired_identity,
2034
char * identity_buffer,
2035
unsigned int identity_buffer_length)
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;
2042
static char * _function_name_ =
2043
"globus_gss_assist_map_and_authorize";
2045
globus_mutex_lock(&globus_i_gsi_gss_assist_mutex);
2047
if(initialized == GLOBUS_FALSE)
2050
result = GLOBUS_GSI_SYSCONFIG_GET_AUTHZ_CONF_FILENAME(&filename);
2052
if(result != GLOBUS_SUCCESS)
2054
error = globus_error_get(result);
2056
if(globus_error_match(
2058
GLOBUS_GSI_SYSCONFIG_MODULE,
2059
GLOBUS_GSI_SYSCONFIG_ERROR_GETTING_AUTHZ_FILENAME)
2062
globus_object_free(error);
2066
result = globus_error_put(error);
2067
globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
2073
result = globus_callout_handle_init(&authz_handle);
2075
if(result != GLOBUS_SUCCESS)
2078
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2080
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_CALLOUT_CONFIG);
2081
globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
2085
result = globus_callout_read_config(authz_handle, filename);
2089
if(result != GLOBUS_SUCCESS)
2091
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_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);
2099
initialized = GLOBUS_TRUE;
2102
globus_mutex_unlock(&globus_i_gsi_gss_assist_mutex);
2105
if(authz_handle == NULL)
2107
return globus_l_gss_assist_gridmap_lookup(
2112
identity_buffer_length);
2116
result = globus_callout_call_type(authz_handle,
2117
GLOBUS_GENERIC_MAPPING_TYPE,
2122
identity_buffer_length);
2124
if(result != GLOBUS_SUCCESS)
2126
error = globus_error_get(result);
2128
if(globus_error_match(
2130
GLOBUS_CALLOUT_MODULE,
2131
GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED)
2134
globus_object_free(error);
2135
result = globus_l_gss_assist_gridmap_lookup(
2140
identity_buffer_length);
2145
result = globus_error_put(error);
2146
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2148
GLOBUS_GSI_GSS_ASSIST_CALLOUT_ERROR);
2153
result = globus_callout_call_type(authz_handle,
2154
GLOBUS_GENERIC_AUTHZ_TYPE,
2157
if(result != GLOBUS_SUCCESS)
2159
error = globus_error_get(result);
2161
if(globus_error_match(
2163
GLOBUS_CALLOUT_MODULE,
2164
GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED)
2167
result = globus_error_put(error);
2168
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2170
GLOBUS_GSI_GSS_ASSIST_CALLOUT_ERROR);
2175
result = GLOBUS_SUCCESS;
2178
globus_object_free(error);
2186
/* globus_gss_assist_map_and_authorize */
2188
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
2191
globus_l_gss_assist_gridmap_lookup(
2192
gss_ctx_id_t context,
2194
char * desired_identity,
2195
char * identity_buffer,
2196
unsigned int identity_buffer_length)
2199
gss_buffer_desc peer_name_buffer;
2200
OM_uint32 major_status;
2201
OM_uint32 minor_status;
2203
globus_result_t result = GLOBUS_SUCCESS;
2205
char * local_identity;
2206
static char * _function_name_ =
2207
"globus_l_gss_assist_gridmap_lookup";
2209
major_status = gss_inquire_context(&minor_status,
2219
if(GSS_ERROR(major_status))
2221
result = minor_status;
2222
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2224
GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
2228
major_status = gss_inquire_context(&minor_status,
2230
initiator ? GLOBUS_NULL : &peer,
2231
initiator ? &peer : GLOBUS_NULL,
2238
if(GSS_ERROR(major_status))
2240
result = minor_status;
2241
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2243
GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
2247
major_status = gss_display_name(&minor_status,
2251
if(GSS_ERROR(major_status))
2253
result = minor_status;
2254
GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
2256
GLOBUS_GSI_GSS_ASSIST_GSSAPI_ERROR);
2257
gss_release_name(&minor_status, &peer);
2261
gss_release_name(&minor_status, &peer);
2263
if(desired_identity == NULL)
2265
rc = globus_gss_assist_gridmap(
2266
peer_name_buffer.value,
2271
GLOBUS_GSI_GSS_ASSIST_ERROR_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;
2278
if(strlen(local_identity) + 1 > identity_buffer_length)
2280
GLOBUS_GSI_GSS_ASSIST_ERROR_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));
2288
strcpy(identity_buffer, local_identity);
2290
free(local_identity);
2294
rc = globus_gss_assist_userok(peer_name_buffer.value,
2298
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2300
GLOBUS_GSI_GSS_ASSIST_GRIDMAP_LOOKUP_FAILED,
2301
(_GASL("Could not map %s to %s\n"),
2302
peer_name_buffer.value,
2304
goto release_peer_name_buffer;
2307
if(strlen(desired_identity) + 1 > identity_buffer_length)
2309
GLOBUS_GSI_GSS_ASSIST_ERROR_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));
2317
strcpy(identity_buffer, desired_identity);
2321
release_peer_name_buffer:
2322
gss_release_buffer(&minor_status, &peer_name_buffer);
2329
* Determine length of the next line on the file stream
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.
2337
* File pointer to inspect
2339
* Pointer to be set to the length
2341
* @retval GLOBUS_SUCCESS
2343
* @retval GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP
2344
* Error with gridmap
2348
globus_l_gss_assist_line_length(
2352
globus_result_t result = GLOBUS_SUCCESS;
2356
static char * _function_name_ =
2357
"globus_l_gss_assist_line_length";
2361
rc = fgetpos(fp, &pos);
2364
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2366
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
2367
(_GASL("Couldn't determine position in file.")));
2368
goto fgetpos_failed;
2371
rc = fscanf(fp, "%*[^\n]%*1[\n]%n", &line_len);
2372
if (line_len == -1 && rc == 0)
2374
/* match failure; see if we have an empty line */
2375
rc = fscanf(fp, "%*1[\n]%n", &line_len);
2378
if (rc < 0 && !feof(fp))
2380
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2382
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
2383
(_GASL("Couldn't determine end of line in file.")));
2388
/* Assume end-of-file without newline */
2390
line_len = ftell(fp);
2393
rc = fsetpos(fp, &pos);
2396
GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
2398
GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_GRIDMAP,
2399
(_GASL("Couldn't set position in file.")));
2400
goto fsetpos_failed;
2410
/* globus_l_gss_assist_line_length() */
2411
#endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */