@@ -43,6 +43,75 @@ static apr_status_t mag_mc_name_attrs_cleanup(void *data)
43
43
return 0 ;
44
44
}
45
45
46
+ static apr_status_t mag_mc_req_name_attrs_cleanup (void * data )
47
+ {
48
+ struct mag_conn * mc = (struct mag_conn * )data ;
49
+
50
+ free (mc -> required_name_attrs );
51
+ free (mc -> required_name_vals );
52
+ mc -> required_name_attrs = NULL ;
53
+ mc -> required_name_vals = NULL ;
54
+ return 0 ;
55
+ }
56
+
57
+ static void mag_set_required_name_attr (request_rec * req ,
58
+ struct mag_conn * mc ,
59
+ struct name_attr * attr )
60
+ {
61
+ size_t count , len ;
62
+ char * val = NULL , * attrval = NULL ;
63
+
64
+ /* Count the existing name attribute and value pairs. Both
65
+ * required_name_attrs and required_name_vals are allocated together and
66
+ * hold the same number of strings, with pairs corresponding by index. */
67
+ for (count = 0 ; mc -> required_name_attrs != NULL &&
68
+ mc -> required_name_attrs [count ] != NULL &&
69
+ mc -> required_name_vals != NULL &&
70
+ mc -> required_name_vals [count ] != NULL ; count ++ );
71
+
72
+ /* Prefer a display value string. */
73
+ if (attr -> display_value .length != 0 ) {
74
+ len = attr -> display_value .length ;
75
+ attrval = attr -> display_value .value ;
76
+ } else if (attr -> value .length != 0 ) {
77
+ len = attr -> value .length ;
78
+ attrval = attr -> value .value ;
79
+ } else {
80
+ ap_log_rerror (APLOG_MARK , APLOG_DEBUG , 0 , req ,
81
+ "no name attribute value available" );
82
+ return ;
83
+ }
84
+
85
+ /* Prepend the value length. */
86
+ val = apr_pcalloc (mc -> pool , sizeof (len ) + len + 1 );
87
+ memcpy (val , & len , sizeof (len ));
88
+ memcpy (val + sizeof (len ), attrval , len );
89
+
90
+ /* Allocate/realloc a new bunch. */
91
+ if (count % 16 == 0 ) {
92
+ size_t size = sizeof (* mc -> required_name_attrs ) * (count + 16 + 2 );
93
+ mc -> required_name_attrs = realloc (mc -> required_name_attrs , size );
94
+ mc -> required_name_vals = realloc (mc -> required_name_vals , size );
95
+ if (!mc -> required_name_attrs || !mc -> required_name_vals ) {
96
+ apr_pool_abort_get (mc -> pool )(ENOMEM );
97
+ }
98
+ apr_pool_userdata_setn (mc , GSS_NAME_ATTR_USERDATA ,
99
+ mag_mc_req_name_attrs_cleanup , mc -> pool );
100
+ }
101
+
102
+ mc -> required_name_attrs [count ] = apr_pstrndup (mc -> pool , attr -> name .value ,
103
+ attr -> name .length );
104
+ mc -> required_name_attrs [count + 1 ] = NULL ;
105
+ mc -> required_name_vals [count ] = val ;
106
+ mc -> required_name_vals [count + 1 ] = NULL ;
107
+
108
+ ap_log_rerror (APLOG_MARK , APLOG_DEBUG , 0 , req ,
109
+ "found name attribute '%s' with length %lu" ,
110
+ mc -> required_name_attrs [count ], len );
111
+ ap_log_rdata (APLOG_MARK , APLOG_DEBUG , req , mc -> required_name_attrs [count ],
112
+ mc -> required_name_vals [count ] + sizeof (len ), len , 0 );
113
+ }
114
+
46
115
static void mc_add_name_attribute (struct mag_conn * mc ,
47
116
const char * name , const char * value )
48
117
{
@@ -221,17 +290,17 @@ gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
221
290
void mag_get_name_attributes (request_rec * req , struct mag_config * cfg ,
222
291
gss_name_t name , struct mag_conn * mc )
223
292
{
224
- if (!cfg -> name_attributes ) {
225
- return ;
226
- }
227
-
228
293
uint32_t maj , min ;
229
294
gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET ;
230
295
struct name_attr attr ;
231
296
char * json = NULL ;
232
297
char * error ;
233
- int count = 0 ;
234
- int i , j ;
298
+ int count = 0 , map_count = 0 ;
299
+ int i ;
300
+
301
+ if (!cfg -> name_attributes && !cfg -> required_na_expr ) {
302
+ return ;
303
+ }
235
304
236
305
maj = gss_inquire_name (& min , name , NULL , NULL , & attrs );
237
306
if (GSS_ERROR (maj )) {
@@ -242,62 +311,77 @@ void mag_get_name_attributes(request_rec *req, struct mag_config *cfg,
242
311
}
243
312
244
313
if (!attrs || attrs -> count == 0 ) {
245
- mc_add_name_attribute (mc , "GSS_NAME_ATTR_ERROR" , "0 attributes found" );
314
+ if (cfg -> name_attributes ) {
315
+ mc_add_name_attribute (mc , "GSS_NAME_ATTR_ERROR" , "0 attributes found" );
316
+ }
317
+ ap_log_rerror (APLOG_MARK , APLOG_DEBUG , 0 , req , "no name attributes found" );
246
318
}
247
319
248
- if (cfg -> name_attributes -> output_json ) {
320
+ if (attrs ) {
321
+ count = attrs -> count ;
322
+ }
249
323
250
- if (attrs ) count = attrs -> count ;
324
+ if (cfg -> name_attributes ) {
325
+ map_count = cfg -> name_attributes -> map_count ;
326
+ }
251
327
328
+ if (cfg -> name_attributes && cfg -> name_attributes -> output_json ) {
252
329
json = apr_psprintf (req -> pool ,
253
330
"{\"name\":\"%s\",\"attributes\":{" ,
254
331
mc -> gss_name );
255
- } else {
256
- count = cfg -> name_attributes -> map_count ;
257
332
}
258
333
334
+ /* Collect all name attributes */
259
335
for (i = 0 ; i < count ; i ++ ) {
260
-
261
336
memset (& attr , 0 , sizeof (struct name_attr ));
262
337
263
- if (cfg -> name_attributes -> output_json ) {
264
- attr .name = attrs -> elements [i ];
265
- for (j = 0 ; j < cfg -> name_attributes -> map_count ; j ++ ) {
338
+ attr .name = attrs -> elements [i ];
339
+ if (map_count ) {
340
+ /* Use the environment variable name matching the attribute name
341
+ * from the map. */
342
+ for (int j = 0 ; j < map_count ; j ++ ) {
266
343
if (strncmp (cfg -> name_attributes -> map [j ].attr_name ,
267
- attrs -> elements [ i ] .value ,
268
- attrs -> elements [ i ] .length ) == 0 ) {
344
+ attr . name .value ,
345
+ attr . name .length ) == 0 ) {
269
346
attr .env_name = cfg -> name_attributes -> map [j ].env_name ;
270
347
break ;
271
348
}
272
349
}
273
- } else {
274
- attr .name .length = strlen (cfg -> name_attributes -> map [i ].attr_name );
275
- attr .name .value = cfg -> name_attributes -> map [i ].attr_name ;
276
- attr .env_name = cfg -> name_attributes -> map [i ].env_name ;
277
350
}
278
-
279
351
attr .number = 0 ;
280
352
attr .more = -1 ;
281
353
do {
282
354
attr .number ++ ;
283
355
attr .value = empty_buffer ;
284
356
attr .display_value = empty_buffer ;
285
357
286
- if (!mag_get_name_attr (req , name , & attr )) break ;
358
+ /* Fetch the next attribute value. */
359
+ if (!mag_get_name_attr (req , name , & attr )) {
360
+ break ;
361
+ }
287
362
288
- if (cfg -> name_attributes -> output_json ) {
363
+ /* Add as a JSON value if needed. */
364
+ if (cfg -> name_attributes && cfg -> name_attributes -> output_json ) {
289
365
mag_add_json_name_attr (req , i == 0 , & attr , & json );
290
366
}
367
+
368
+ /* Add as an environment variable if needed. */
291
369
if (attr .env_name ) {
292
370
mag_set_env_name_attr (req , mc , & attr );
293
371
}
294
372
373
+ /* Add to the list of name attributes lined up for the requirement
374
+ * check if needed. */
375
+ if (cfg -> required_na_expr ) {
376
+ mag_set_required_name_attr (req , mc , & attr );
377
+ }
378
+
295
379
gss_release_buffer (& min , & attr .value );
296
380
gss_release_buffer (& min , & attr .display_value );
297
381
} while (attr .more != 0 );
298
382
}
299
383
300
- if (cfg -> name_attributes -> output_json ) {
384
+ if (cfg -> name_attributes && cfg -> name_attributes -> output_json ) {
301
385
json = apr_psprintf (req -> pool , "%s}}" , json );
302
386
mc_add_name_attribute (mc , "GSS_NAME_ATTRS_JSON" , json );
303
387
}
@@ -393,6 +477,14 @@ void mag_set_req_data(request_rec *req,
393
477
mag_export_req_env (req , mc -> env );
394
478
}
395
479
480
+ void mag_set_req_attr_fail (request_rec * req , struct mag_config * cfg ,
481
+ struct mag_conn * mc )
482
+ {
483
+ apr_table_set (mc -> env , "GSS_NAME_ATTR_ERROR" ,
484
+ "required name attributes check unsatisfied" );
485
+ mag_set_req_data (req , cfg , mc );
486
+ }
487
+
396
488
void mag_publish_error (request_rec * req , uint32_t maj , uint32_t min ,
397
489
const char * gss_err , const char * mag_err )
398
490
{
0 commit comments