/[pdpsoft]/trunk/grid-mw-security/ees/src/aos/aos.c
ViewVC logotype

Contents of /trunk/grid-mw-security/ees/src/aos/aos.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1754 - (show annotations) (download) (as text)
Thu Jun 10 16:35:55 2010 UTC (11 years, 7 months ago) by aramv
File MIME type: text/x-chdr
File size: 14361 byte(s)
Fixed most memleaks in localaccount/localgroup plugin
1 #include "plugin_manager.h"
2 #include "_aos.h"
3 #include "eef_aos.h"
4
5 static pthread_key_t _aos_key;
6 static pthread_once_t _aos_key_once = PTHREAD_ONCE_INIT; /* Normally not okay to do initialisation outside of a function, but this way it (hopefully) will only be set one - during compile time */
7 static struct aos_state_s * _global_state;
8
9 /* internal methods */
10
11 /**
12 * returns _is_initialized
13 */
14 int aos_is_initialized(){
15 return _is_initialized;
16 }
17
18 /**
19 * sets threading flag
20 */
21 void aos_start_threading(){
22 _is_threading = 1;
23 }
24
25 /**
26 * returns a pointer to an aos_storage_t struct that corresponds to the current thread context. If the current context is not threaded, a pointer to a global storage struct is returned.
27 */
28 aos_state_t * aos_get_state(void){
29 pid_t tid;
30 aos_state_t * state = NULL;
31
32 tid = syscall(SYS_gettid);
33 /*tid = gettid();*/
34
35 if(!_is_threading){
36 return _global_state;
37 }
38
39 /* Try to get TLS */
40 state = pthread_getspecific(_aos_key);
41 if(state == 0) {
42 /* Create new TLS */
43 if((state = calloc(1, sizeof(aos_state_t)))){
44 state->last_context = NULL;
45 if((state->current_storage = calloc(1, sizeof(aos_storage_t)))){
46 state->current_storage->list_contexts = NULL;
47 _is_initialized = 1;
48 state->saved_storage = state->current_storage;
49 pthread_setspecific(_aos_key, state);
50 return state;
51 }
52 }
53 } else {
54 return state;
55 }
56 return NULL;
57 }
58
59 aos_storage_t* aos_get_storage(){
60 aos_state_t* iterator = aos_get_state();
61 return iterator->current_storage;
62 }
63
64 EES_RC aos_free_state(aos_state_t* state){
65 printf("Freeing state at %p\n", state);
66 aos_free_storage(state->saved_storage);
67 state->saved_storage = NULL;
68 state->last_context = NULL;
69 }
70
71 /**
72 * Frees storage struct pointed to by storage pointer
73 */
74 EES_RC aos_free_storage(aos_storage_t* storage){
75 aos_context_t *context = NULL, *next_context = NULL;
76 aos_attribute_t *attribute = NULL, *next_attribute = NULL;
77 int attribute_count = 0;
78
79 if(!storage){
80 return EES_FAILURE;
81 }
82
83 EEF_log(LOG_DEBUG, "Cleaning aos storage at %p\n", storage);
84
85 context = storage->list_contexts;
86
87 while(context){
88 next_context = context->next;
89 attribute = context->list_attributes;
90 while(attribute){
91 next_attribute = attribute->next;
92 free(attribute->id);
93 free(attribute->issuer);
94 /*free(attribute->type);*/
95 if(attribute->needs_free){
96 EEF_log(LOG_DEBUG, "Freeing arg data %i at %p\n",attribute_count, attribute->data);
97 free(attribute->data);
98 }
99 free(attribute);
100 attribute = next_attribute;
101 attribute_count++;
102 }
103 /* free here */
104 EEF_log(LOG_DEBUG, "Freeing context at %p\n", context);
105 context->next = NULL;
106 context->list_attributes = NULL;
107 free(context);
108 context = next_context;
109 }
110 storage->list_contexts = NULL;
111 free(storage);
112 storage = NULL;
113 return EES_SUCCESS;
114 }
115
116 /* base functions */
117
118 /**
119 * Returns a pointer to a freshly allocated aos_context_t struct
120 */
121 aos_context_t * createContext(aos_context_class_t context_class){
122 aos_context_t * context;
123 if((context = calloc(1, sizeof(aos_context_t)))){
124 context->context_class = context_class;
125 context->list_attributes = NULL;
126 context->last_attribute = NULL;
127 context->next = NULL;
128 }
129 /*printf("Context of type %i created at %p\n", context_class, context);*/
130 return context;
131 }
132
133 /**
134 * Adds supplied context to storage attained through aos_get_storage()
135 */
136 EES_RC addContext(aos_context_t* context){
137 aos_state_t* iterator = aos_get_state();
138 aos_storage_t* storage = iterator->saved_storage;
139 aos_context_t* tmp_context = NULL;
140
141 EEF_log(LOG_DEBUG, "Adding context at %p to storage at %p\n", context, iterator->current_storage);
142 if(!storage){
143 EEF_log(LOG_ERR, "No storage available at %p", storage);
144 return EES_FAILURE;
145 }
146 if(storage->list_contexts != NULL){
147 if((tmp_context = storage->list_contexts)!=NULL){
148 while(tmp_context->next){
149 if(tmp_context == context){
150 EEF_log(LOG_ERR, "The context you're trying to add was already added!\n");
151 return EES_FAILURE;
152 }
153 tmp_context = tmp_context->next;
154 }
155 }
156 tmp_context->next = context;
157 EEF_log(LOG_DEBUG, "Inserted at %p\n", tmp_context);
158 /*printf("Inserted at %p\n", tmp_context);*/
159 } else {
160 storage->list_contexts = context;
161 EEF_log(LOG_DEBUG, "Created at %p\n", context);
162 /*printf("List created at %p\n", context);*/
163 }
164 aos_set_iterator(context);
165
166 /*eef_log(LOG_DEBUG, "Copied context to %p\n", storage->last_context);*/
167 return EES_SUCCESS;
168 }
169
170 EES_RC rewindContexts(aos_storage_t* storage){
171 aos_state_t* state = aos_get_state();
172 /* not using storage parameter anymore */
173
174 if(state){
175 state->current_storage = state->saved_storage;
176
177 if(state->current_storage){
178 aos_set_iterator(state->current_storage->list_contexts);
179 return EES_SUCCESS;
180 } else {
181 EEF_log(LOG_ERR, "Unable to aquire AOS handle in rewindContexts()\n");
182 }
183 }
184 return EES_FAILURE;
185 }
186
187 EES_RC aos_set_iterator(aos_context_t* context){
188 aos_state_t* state = aos_get_state();
189 if(state->current_storage){
190 /*printf("Setting iterator for %p to %p\n", state->current_storage, context);*/
191 state->last_context = context;
192 return EES_SUCCESS;
193 } else {
194 EEF_log(LOG_ERR, "Invalid storage passed to aos_set_iterator(): %p\n", state->current_storage);
195 }
196 return EES_FAILURE;
197 }
198
199 aos_context_t* aos_get_iterator(void){
200 aos_state_t* state = aos_get_state();
201 if(state->current_storage){
202 /*printf("Getting iterator for %p as %p\n", state->current_storage, state->last_context);*/
203 if(state->last_context){
204 return state->last_context;
205 }
206 } else {
207 EEF_log(LOG_ERR, "Invalid storage passed to aos_set_iterator(): %p\n", state->current_storage);
208 }
209 return NULL;
210 }
211
212 /**
213 * returns the next aos_context_t pointer with the supplied context_class from the list of contexts in the supplied storage.
214 * will fall through and try to use global storage in case nothing was found
215 */
216 aos_context_t * getNextContext(aos_context_class_t context_class, aos_storage_t* storage){
217 aos_state_t* state = aos_get_state();
218 aos_context_t* current_context = aos_get_iterator();
219
220 /* find context type */
221 if(context_class != ANY){
222 while(current_context != NULL){
223 if((current_context->context_class == context_class)){
224 /* Found context */
225 break;
226 }
227 current_context = current_context->next;
228 }
229 }
230
231 /* save state */
232 if((current_context == NULL) && (storage != _global_state->current_storage) && (state->current_storage != _global_state->current_storage)){
233 /* Retry with global storage */
234 state->current_storage = _global_state->current_storage;
235 aos_set_iterator(_global_state->current_storage->list_contexts);
236 current_context = getNextContext(context_class, _global_state->current_storage);
237 }
238
239 /* save iterator */
240 if(current_context){
241 aos_set_iterator(current_context->next);
242 } else {
243 aos_set_iterator(NULL);
244 }
245
246 return current_context;
247 }
248
249 /**
250 * Sets the obligation name in the struct pointed to by the supplied pointer context to supplied obligation
251 */
252 void setContextObligationId(aos_context_t* context, char * obligation){
253 if(context->context_class == OBLIGATION){
254 context->obligation_name = obligation;
255 }
256 }
257
258 /**
259 * Returns the obligation name from the supplied context
260 */
261 char* getContextObligationId(aos_context_t* context){
262 return context->obligation_name;
263 }
264
265 /**
266 * Returns a pointer to a freshly allocated aos_attribute_t struct
267 */
268 aos_attribute_t* createAttribute(void){
269 aos_attribute_t* attribute = NULL;
270 if((attribute = calloc(1, sizeof(aos_attribute_t)))){
271 attribute->next = NULL;
272 attribute->setting_plugin = get_running_plugin();
273 }
274 return attribute;
275 }
276
277 /**
278 * Adds supplied attribute to supplied context
279 */
280 EES_RC addAttribute(aos_context_t * context, aos_attribute_t* attribute){
281 if(context->last_attribute){
282 context->last_attribute->next = attribute;
283 } else {
284 context->list_attributes = attribute;
285 context->last_attribute = NULL;
286 }
287 context->last_attribute = attribute;
288 return EES_SUCCESS;
289 }
290
291 EES_RC rewindAttributes(aos_context_t* context){
292 context->last_attribute = NULL;
293 return EES_SUCCESS;
294 }
295
296 /**
297 * returns the next aos_attribute_t pointer from list of attributes in the supplied context
298 */
299 aos_attribute_t* getNextAttribute(aos_context_t* context){
300 aos_attribute_t* attribute = NULL;
301 if(context->last_attribute){
302 attribute = context->last_attribute->next;
303 } else {
304 attribute = context->list_attributes;
305 }
306 context->last_attribute = attribute;
307 return attribute;
308 }
309
310 /**
311 * removes a supplied attribute from the supplied context
312 */
313 EES_RC destroyAttribute(aos_context_t* context, aos_attribute_t* attribute){
314 aos_attribute_t *last_attribute = NULL, *current_attribute = NULL;
315 for(current_attribute = context->list_attributes; current_attribute != NULL; last_attribute = current_attribute, current_attribute = current_attribute->next){
316 if(current_attribute == attribute){
317 if(current_attribute->setting_plugin != get_running_plugin()){
318 EEF_log(LOG_ERR, "Argument %s is not owned by running plugin %s", current_attribute->id, get_running_plugin()->name);
319 return EES_FAILURE;
320 }
321 free(attribute->data);
322 free(attribute);
323 attribute = NULL;
324 if(last_attribute == NULL){
325 context->list_attributes = current_attribute->next;
326 } else {
327 last_attribute->next = current_attribute->next;
328 }
329 break;
330 }
331 }
332
333 if(current_attribute){
334 free(current_attribute->data);
335 free(current_attribute);
336 current_attribute = NULL;
337 return EES_SUCCESS;
338 }
339 return EES_FAILURE;
340 }
341
342 /**
343 * sets attribute id in supplied attribute
344 */
345 EES_RC setAttributeId(aos_attribute_t* attribute, char* id){
346 free(attribute->id);
347 attribute->id = NULL;
348 if(id != NULL){
349 attribute->id = strdup(id);
350 } else {
351 EEF_log(LOG_ERR, "setAttributeId(), tried to set NULL id\n");
352 }
353 return EES_SUCCESS;
354 }
355
356 /**
357 * sets attribute issuer in supplied attribute
358 */
359 EES_RC setAttributeIssuer(aos_attribute_t* attribute, char* issuer){
360 free(attribute->issuer);
361 attribute->issuer = NULL;
362 if(issuer != NULL){
363 printf("setAttributeIssuer() %s!\n", issuer);
364 attribute->issuer = strdup(issuer);
365 } else {
366 /*EEF_log(LOG_ERR, "setAttributeIssuer(), tried to set NULL issuer\n");*/
367 }
368 return EES_SUCCESS;
369 }
370
371 /**
372 * sets attribute value in supplied attribute
373 */
374 EES_RC setAttributeValue(aos_attribute_t* attribute, const void* value, size_t size){
375 if(value != NULL){
376 if(size == 0) {
377 attribute->data = value;
378 attribute->needs_free = 0;
379 } else {
380 attribute->data = calloc(1, size+1);
381 memcpy(attribute->data, value, size);
382 attribute->needs_free = 1;
383 }
384 } else {
385 return EES_FAILURE;
386 }
387 return EES_SUCCESS;
388 }
389
390 /**
391 * sets attribute type in supplied attribute
392 */
393 EES_RC setAttributeType(aos_attribute_t * attribute, char* type){
394 attribute->type = type;
395 return EES_SUCCESS;
396 }
397
398 /**
399 * returns id from supplied attribute
400 */
401 char* getAttributeId(aos_attribute_t* attribute){
402 return attribute->id;
403 }
404
405 /**
406 * returns issuer from supplied attribute
407 */
408 char* getAttributeIssuer(aos_attribute_t* attribute){
409 return attribute->issuer;
410 }
411
412 /**
413 * returns data from supplied attribute casted to a char*
414 */
415 char* getAttributeValueAsString(aos_attribute_t* attribute){
416 return (char*) attribute->data;
417 }
418
419 /**
420 * returns data from supplied attribute casted to a int
421 */
422 int getAttributeValueAsInt(aos_attribute_t* attribute){
423 char* string = getAttributeValueAsString(attribute);
424 return strtol(string, NULL, 10);
425 }
426
427 /* AOS control functions */
428
429 /**
430 * Initializes the AOS and creates thread-local storage key
431 */
432 EES_RC AOS_Init (void){
433 _is_threading = 0;
434 pthread_once(&_aos_key_once, aos_make_key);
435
436 if((_global_state = calloc(1, sizeof(aos_state_t)))){
437 _global_state->last_context = NULL;
438 if((_global_state->current_storage = calloc(1, sizeof(aos_storage_t)))){
439 _global_state->current_storage->list_contexts = NULL;
440 _global_state->saved_storage = _global_state->current_storage;
441 _is_initialized = 1;
442 return EES_SUCCESS;
443 }
444 }
445
446 return EES_FAILURE;
447 }
448
449 /**
450 * Creates thread-local storage key
451 */
452 void aos_make_key(void){
453 pthread_key_create(&_aos_key, aos_free_key);
454 }
455
456 /**
457 * Frees thread-local storage key
458 */
459 void aos_free_key(void* state){
460 pid_t tid;
461 aos_storage_t* storage;
462 aos_state_t* tmp_state = (aos_state_t*) state;
463 tid = syscall(SYS_gettid);
464 EEF_log(LOG_DEBUG, "Killing thread %i\n", tid);
465 aos_free_state(tmp_state);
466 }
467
468 /**
469 * Frees thread-local storage for this thread
470 */
471 EES_RC AOS_Clean(void){
472 pid_t tid;
473 tid = syscall(SYS_gettid);
474 EEF_log(LOG_DEBUG, "Killing thread %i\n", tid);
475 if(_is_threading){
476 aos_free_state(aos_get_state());
477 }
478 return EES_SUCCESS;
479 }
480
481 /**
482 * Terminates AOS, deleting the global storage key
483 */
484 EES_RC AOS_Term (void){
485 _is_threading = 0;
486 aos_free_state(_global_state);
487 pthread_setspecific(_aos_key, NULL);
488 pthread_key_delete(_aos_key);
489 _is_initialized = 0;
490 return EES_SUCCESS;
491 }
492
493 /**
494 * Dumps out all the data present in the AOS, as seen from the current thread's perspective
495 */
496 EES_RC aos_dump_argslist (void) {
497 char *log_str = "aos_dump";
498 aos_context_t *context = NULL;
499 aos_attribute_t *attribute = NULL;
500 char *attribute_name = NULL;
501 char *attribute_value = NULL;
502
503 EEF_log(LOG_DEBUG, "Dumping aos");
504
505 rewindContexts(NULL);
506
507 while((context = getNextContext(ANY, NULL)) != NULL){
508 EEF_log(LOG_DEBUG, "Context %p class: %i\n", context, context->context_class);
509 rewindAttributes(context);
510 while((attribute = getNextAttribute(context)) != NULL){
511 attribute_name = getAttributeId(attribute);
512 attribute_value = getAttributeValueAsString(attribute);
513 if(attribute_name && attribute_value){
514 EEF_log(LOG_DEBUG, "\t%s=%s\n", attribute_name, attribute_value);
515 }
516 }
517 }
518
519 return EES_SUCCESS;
520 }
521

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28