1    | /***************************************
2    |   $Revision: 1.27 $
3    | 
4    |   UP module utilities
5    | 
6    |   Status: REVIEWED, NOT TESTED
7    | 
8    |   Author(s):       Engin Gunduz
9    | 
10   |   ******************/ /******************
11   |   Modification History:
12   |         engin (17/01/2000) Created.
13   | 		denis (31/08/2001) Modified for new API
14   |   ******************/ /******************
15   |   Copyright (c) 2000,2001,2002                    RIPE NCC
16   |  
17   |   All Rights Reserved
18   |   
19   |   Permission to use, copy, modify, and distribute this software and its
20   |   documentation for any purpose and without fee is hereby granted,
21   |   provided that the above copyright notice appear in all copies and that
22   |   both that copyright notice and this permission notice appear in
23   |   supporting documentation, and that the name of the author not be
24   |   used in advertising or publicity pertaining to distribution of the
25   |   software without specific, written prior permission.
26   |   
27   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
28   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
29   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
30   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
31   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
32   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33   |  ***************************************/
34   | 
35   | #include <time.h>
36   | #include "dbupdate.h"
37   | #include "UP_extrnl_syntax.h"
38   | #include "ud.h"
39   | #include "notification.h"
40   | 
41   | extern int tracing;
42   | extern char * overridecryptedpw;
43   | extern int test_mode;
44   | extern char * updlog;
45   | extern char * update_host;
46   | extern int update_port;
47   | extern char * query_host;
48   | extern int query_port;
49   | extern char * humailbox;
50   | extern char * autobox;
51   | extern char * netupdclientIP;
52   | 
53   | extern int reading_from_mail;
54   | extern int networkupdate;
55   | extern int webupdate; 
56   | extern char *netupdclientIP;
57   | 
58   | extern char *update_mail_sender;
59   | extern char *update_mail_subject;
60   | extern char *update_mail_date;
61   | extern char *update_mail_ID;
62   | extern char *update_mail_cc;
63   | 
64   | extern char *header_type;
65   | extern char *text_type;
66   | 
67   | extern char *current_source;
68   | extern char *DBhost;
69   | extern int  DBport;
70   | extern char *DBuser;
71   | extern char *DBname;
72   | extern char *DBpasswd;
73   | 
74   | extern char * allocmnt;
75   | 
76   | 
77   | /* authorise function takes the auth_vector, credentials struct, and 'overriden'
78   |    variable. If overriden == 1, then it immediately returns UP_AUTH_OK 
79   |    (because this means that the update contained a valid override attribute).
80   |    Else, it goes through the auth_vector and when it finds a an "auth:"
81   |    attribute which passes, then it returns UP_AUTH_OK. Otherwise, it returns
82   |    UP_AUF (authorisation failed) */
83   |    
84   | int authorise(GSList * auth_vector, credentials_struct credentials, int overriden)
85   | {
86   |   int result = 0;
87   | 
88   |   if (tracing)
89   |   {
90   |     printf("TRACING: authorise started with override: %i\n", overriden);
91   |   }
92   |     
93   |   /* If 'overriden' variable is 1, then return UP_AUTH_OK immediately */
94   |   if (overriden == 1)
95   |   {
96   |     return UP_AUTH_OK;
97   |   }
98   |   else
99   |   {
100  |     result = AU_authorise(auth_vector, credentials);
101  |     if (tracing)
102  | 	{
103  |       printf("TRACING: authorise: AU_authorise returned %i\n", result);
104  |     }
105  |     
106  |     if (result > 0)
107  | 	{
108  |       return UP_AUTH_OK;
109  |     }
110  |     else
111  | 	{
112  |       return UP_AUF; /* authorisation failed */
113  |     }
114  |   }
115  | }
116  | 
117  | 
118  | 
119  | /* interprets the result string coming from RIPupd
120  |    It is called by send_object_db.
121  |    It returns the error no returned from RIPupd.  */
122  |    
123  | int interpret_ripdb_result(const char * string)
124  | {
125  |    char * error_no = NULL;
126  |    char ** temp = NULL, ** temp2 = NULL;
127  |    int i;
128  |    int err = 0;
129  |      
130  |   /* if the string is NULL or empty, then return error */
131  |   if (string == NULL || strlen(string) == 0)
132  |   {
133  |     return 0; 
134  |   }
135  | 
136  |   /* split the string into lines */
137  |   temp = g_strsplit(string , "\n", 0);
138  |   for (i = 0; temp[i] != NULL; i++)
139  |   {
140  |     if (i == 0)
141  | 	{ /* this line must contain "%ERROR " string in the beginning */
142  |       temp2 = g_strsplit(temp[0], " ", 0);
143  |       error_no = strdup(temp2[1]);
144  |       g_strfreev(temp2);
145  |       err = atoi(error_no);
146  |       if (tracing)
147  | 	  {
148  |         printf("TRACING: interpret_ripdb_result: error_no is [%s]\n", error_no);
149  |       }
150  |     }
151  | 	else if (error_no != NULL && strcmp(error_no, "0") != 0)
152  | 	{
153  |     }
154  |   }
155  |   g_strfreev(temp);
156  |   if (error_no != NULL)
157  |   {
158  |     free(error_no);
159  |   }
160  |   return err; /* 0 means no error in this context */
161  | }
162  | 
163  | 
164  | 
165  | /* Gets assigned NIC hdl from the string that is returned from 
166  |    RIPupdate */
167  | void get_assigned_nic(char * nic_hdl, const char * string)
168  | {
169  |    char * error_no = NULL;
170  |    char ** temp = NULL, ** temp2 = NULL;
171  |    int i;
172  |      
173  |   if (tracing)
174  |   {                                
175  |       printf("TRACING: get_assigned_nic is running\n");
176  |   }
177  | 
178  |   /* if the string is NULL or empty, then return error */
179  |   if (string == NULL || strlen(string) == 0)
180  |   {
181  |     return; 
182  |   }
183  | 
184  |   /* split the string into lines */
185  |   temp = g_strsplit(string , "\n", 0);
186  |   for (i = 0; temp[i] != NULL; i++)
187  |   {
188  |     if (i == 0)
189  | 	{ /* this line must contain "%ERROR " string in the beginning */
190  |       temp2 = g_strsplit(temp[0], " ", 0);
191  |       error_no = strdup(temp2[1]);
192  |       g_strfreev(temp2);
193  |       if (tracing)
194  | 	  {
195  |         printf("TRACING: get_assigned_nic: error_no is [%s]\n", error_no);
196  |       }
197  |     }
198  | 	else if (error_no != NULL && strcmp(error_no, "0") != 0)
199  | 	{
200  |     }
201  | 	else if (error_no != NULL && strcmp(error_no, "0") == 0 && i == 1)
202  | 	{ /* look for assigned NIC hdl */
203  |       /* in the second line RIPupdate returns for example "I[65][EK3-RIPE]" We
204  |          need to extract EK3-RIPE part */
205  |       nic_hdl = strncpy(nic_hdl, rindex(temp[i],'[') + 1 ,  
206  |                                  rindex(temp[i],']') - rindex(temp[i],'[') - 1);
207  |       nic_hdl[rindex(temp[i],']') - rindex(temp[i],'[') - 1] = '\0';
208  |       if (tracing && nic_hdl != NULL)
209  | 	  {
210  |         printf("TRACING: get_assigned_nic will return [%s]\n", nic_hdl);
211  |       }
212  |       g_strfreev(temp);
213  |       return;
214  |     }
215  |   }
216  |   g_strfreev(temp);
217  |   return;
218  | }
219  | 
220  | 
221  | 
222  | /* Obtains a transaction ID for an object. Will be called from send_object_db */
223  | int up_get_transaction_id()
224  | {
225  |   SQ_connection_t * sql_connection;
226  |   SQ_result_set_t *result;
227  |   int error;
228  |   long new_id;
229  | 
230  |   sql_connection = SQ_get_connection(DBhost, DBport, DBname, DBuser, DBpasswd); 
231  |   if (!sql_connection)
232  |   {
233  |     fprintf(stderr, "No SQL connection\n");
234  |     exit(1);
235  |   }
236  |   error = SQ_execute_query(sql_connection, "INSERT INTO tid VALUES(NULL)", &result);
237  |   if (error)
238  |   {
239  |     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
240  |     exit(1);
241  |   }
242  | 
243  |   new_id = mysql_insert_id(sql_connection);
244  | 
245  |   SQ_close_connection(sql_connection);  
246  | 
247  |   return new_id;
248  | }
249  | 
250  | 
251  | 
252  | /* sends the object to the database. char * operation is either 'ADD' ,'DEL' or 'UPD'
253  |    assigned_NIC is filled in if this is a person/role creation with AUTO nic hdl 
254  |    assigned_NIC must be allocated enough memory before send_object_db is called 
255  |    
256  |    If the called do not expect a NIC hdl back, then assigned_NIC can be given NULL
257  |    */
258  | up_ripupd_result_struct * send_object_db(rpsl_object_t *object, char * assigned_NIC, char * operation)
259  | {
260  |   int sockfd, numbytes;  
261  |   char buf[MAXDATASIZE + 1];
262  |   struct hostent *he;
263  |   struct sockaddr_in their_addr; /* connector's address information */
264  |   char *result_string = NULL;
265  |   int err = 0;
266  |   char *to_be_sent = NULL;
267  |   int tr_id;
268  |   char * tr_id_str;
269  |   char * tempstr;
270  |   rpsl_object_t *sent_object;
271  |   rpsl_attr_t *removed_attr;
272  |   rpsl_error_t return_error;
273  | 
274  |   up_ripupd_result_struct * return_struct;
275  | 
276  |   if (tracing)
277  |   { 
278  |     printf("TRACING: send_object_db is running: assigned_NIC : [%s]; operation: [%s]\n", assigned_NIC ? assigned_NIC : "", operation);
279  |   }
280  |   return_struct = (up_ripupd_result_struct *)malloc(sizeof(up_ripupd_result_struct));
281  |   return_struct->error_str = NULL;
282  |   
283  |   /* copy the object, remove the override password and create a text string */
284  |   sent_object = rpsl_object_copy(object);
285  |   removed_attr = rpsl_object_remove_attr_name(sent_object,"override",&return_error);
286  |   to_be_sent = rpsl_object_get_text(sent_object,0);
287  |   rpsl_object_delete(sent_object);
288  | 
289  |   if (tracing)
290  |   { 
291  |     printf("TRACING: send_object_db: to_be_sent : [\n%s]\n", to_be_sent);
292  |   }
293  | 
294  |   /* get the transaction ID, to be sent to RIPupdate*/
295  |   tr_id = up_get_transaction_id();
296  | 
297  |   /* convert it into a string */
298  |   tr_id_str = (char *)malloc(64);
299  |   sprintf(tr_id_str, "%d", tr_id);
300  | 
301  |   if (tracing)
302  |   { 
303  |     printf("TRACING: send_object_db: tr_id_str : [%s]\n", tr_id_str);
304  |   }
305  | 
306  |   if ((he=gethostbyname(update_host)) == NULL)
307  |   {  /* get the host info */
308  |       perror("gethostbyname");
309  |       exit(1);
310  |   }
311  | 
312  |   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
313  |   {
314  |       perror("socket");
315  |       exit(1);
316  |   }
317  | 
318  |   their_addr.sin_family = AF_INET;  	/* host byte order */
319  |   their_addr.sin_port = htons(update_port);    /* short, network byte order */
320  |   their_addr.sin_addr = *((struct in_addr *)he->h_addr);
321  |   bzero(&(their_addr.sin_zero), 8); 	/* zero the rest of the struct */
322  | 
323  | 
324  |   if (connect(sockfd, (struct sockaddr *)&their_addr, 
325  |     									sizeof(struct sockaddr)) == -1)
326  |   {
327  |       perror("connect");
328  |       exit(1);
329  |   }
330  | 
331  |   if (send(sockfd, operation , strlen(operation), 0) == -1)
332  |       perror("send");
333  |   if (send(sockfd, " ", strlen(" "), 0) == -1)
334  |       perror("send");	 
335  |   if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
336  |       perror("send");	 
337  |   if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
338  |       perror("send");
339  |   if (send(sockfd, to_be_sent, strlen(to_be_sent), 0) == -1)
340  |       perror("send");
341  |   if (send(sockfd, "\n\n", 2, 0)  == -1)
342  |       perror("send");
343  |   /* send the ACK now */
344  |   if (send(sockfd, "ACK ",strlen("ACK "), 0)  == -1)
345  |       perror("send");
346  |   if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
347  |       perror("send");	 
348  |   if (send(sockfd, "\n\n",strlen("\n\n"), 0)  == -1)
349  |       perror("send");
350  | 
351  |   if (tracing)
352  |   { 
353  |     printf("TRACING: send_object_db: send complete\n");
354  |   }
355  |       
356  | 
357  |   while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0)
358  |   {
359  |       buf[numbytes] = '\0';
360  |       if (tracing)
361  |       {
362  |     	printf("received from socket [\n%s]\n",buf);
363  |       }
364  |       if (result_string == NULL)
365  |       {
366  |     	result_string = strdup(buf);
367  |       }
368  |       else
369  |       {
370  |     	result_string = (char *)realloc(result_string, 
371  |     					   strlen(result_string) + strlen(buf) + 1);
372  |     	result_string = strcat(result_string, buf);
373  |       }
374  |       if (strstr(result_string,"\n\n") != NULL)
375  |       { /* if the result_string contains
376  |     	 an empty line at the end, we will close */
377  |     	break;
378  |       };
379  |   }
380  | 
381  |   free(tr_id_str);
382  |   err = interpret_ripdb_result(result_string);
383  | 
384  |   if (tracing)
385  |   { 
386  |     printf("TRACING: send_object_db: interpret_ripdb_result returned : [%i]\n", err);
387  |   }
388  | 
389  |   if (assigned_NIC != NULL)
390  |   { /* if the caller of the function expected to get a NIC handle */
391  |     get_assigned_nic(assigned_NIC, result_string);
392  |   }
393  |   close(sockfd);
394  |   free(to_be_sent);
395  |   return_struct->result = err;
396  |   
397  |   /*return_struct->error_str = strdup(result_string); */
398  |   /* According to the error no got from RIPupdate, construct an error string  */
399  |   switch (return_struct->result)
400  |   {
401  |     case 0: break; 
402  |     case ERROR_U_MEM: 
403  |     case ERROR_U_DBS:
404  |     case ERROR_U_BADOP:
405  |     case ERROR_U_COP:
406  |     case ERROR_U_NSUP:
407  |     case ERROR_U_BUG:
408  |       tempstr = (char *)malloc(1024);
409  |       snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
410  |     	  return_struct->result);
411  |       return_struct->error_str = tempstr;
412  |       break; 
413  |     case ERROR_U_OBJ:
414  |       if (tracing)
415  |       {
416  |          printf("\nresult_string [%s]\n\n", result_string);
417  |       }
418  |       tempstr = (char *)malloc(1024);
419  |       /* if the object contains refs to unknown objects */
420  |       if (strstr(result_string, "dummy") != NULL || 
421  |             strstr(result_string, "reference cannot be resolved") != NULL )
422  |       {
423  |     	/* if the response from RIPupd contains "dummy not allowed" string 
424  |            or a reference that cannot be resolved */
425  |     	snprintf(tempstr, 1024, "***Error: Unknown object referenced");
426  |       }
427  | 	  else if (strstr(result_string, "key-cert") != NULL)
428  | 	  {
429  |       /* if the response from RIPupd contains "no key-cert object" string */
430  |       snprintf(tempstr, 1024, "***Error: Unknown key-cert object referenced"); 
431  |       }
432  |       else
433  |       {
434  |       /* then, the object is referenced from other objects */
435  |     	snprintf(tempstr, 1024, "***Error: Object is referenced from other objects");
436  |       }
437  |       return_struct->error_str = tempstr;
438  |       break; 
439  |     case ERROR_U_AUT:
440  |       tempstr = (char *)malloc(1024);
441  |       snprintf(tempstr, 1024, "***Error: Membership authorisation failure");
442  |       return_struct->error_str = tempstr;
443  |       break; 
444  |     default: 
445  |       tempstr = (char *)malloc(1024);
446  |       snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
447  |     	  return_struct->result);
448  |       return_struct->error_str = tempstr;
449  |       break; 
450  |   }
451  |   return return_struct; 
452  | }
453  | 
454  | 
455  | 
456  | /* takes an object (pre-parsed) and returns its first attrib if it is not
457  |    a person/role, and returns the nic-hdl if it is a person/role object */
458  | char * get_search_key(rpsl_object_t *object, const char * type)
459  | {
460  |     char *primary_key = NULL;
461  | 	char *lctype;
462  | 	GList *attr_list;
463  | 
464  |     if(object == NULL) return NULL;
465  | 	
466  | 	lctype = strdup(type);
467  | 	g_strdown(lctype);
468  | 	if ( strcmp(lctype, "person") == 0 || strcmp(lctype, "role") == 0 )
469  | 	{
470  | 		/* this is a person or role object */
471  | 		/* get the nic-hdl attribute */
472  | 		attr_list = rpsl_object_get_attr(object, "nic-hdl");
473  | 	}
474  | 	else
475  | 	{
476  | 		/* this is NOT a person or role object */
477  | 		/* get the class attribute */
478  | 		attr_list = rpsl_object_get_attr(object, type);
479  | 	}
480  | 
481  | 	if ( attr_list )
482  | 	{
483  | 		primary_key = rpsl_attr_get_clean_value((rpsl_attr_t *)(attr_list->data));
484  | 	}
485  | 	free(lctype);
486  | 	return primary_key ;
487  | }
488  | 
489  | 
490  | 
491  | /* sends char * arg to the specified host's specified port, and
492  |    returns the reply as a string. This is used to query the
493  |    whois host. Probably we must use WC (whois client) module here,
494  |    but it must be extented */
495  | char * send_and_get(char * host, int port, char * arg)
496  | {
497  |         int sockfd, numbytes; 
498  |         char * result = NULL; 
499  |         char buf[MAXDATASIZE + 1];
500  |         struct hostent *he;
501  |         struct sockaddr_in their_addr; /* connector's address information */
502  |   
503  |         if(tracing)
504  | 		{ 
505  |           printf("TRACING: send_and_get: arg : [%s]; port: [%i]; host: [%s]\n", arg, port, host);
506  |         }
507  | 
508  |         if ((he=gethostbyname(host)) == NULL)
509  | 		{  /* get the host info */
510  |             perror("gethostbyname");
511  |             exit(1);
512  |         }
513  | 
514  |         if(tracing) 
515  | 		{ 
516  |           printf("TRACING: send_and_get: called gethostbyname\n");
517  |         }
518  | 
519  |         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
520  | 		{
521  |             perror("socket");
522  |             exit(1);
523  |         }
524  | 
525  |         if(tracing)
526  | 		{ 
527  |           printf("TRACING: send_and_get: called socket\n");
528  |         }
529  | 
530  |         their_addr.sin_family = AF_INET;      /* host byte order */
531  |         their_addr.sin_port = htons(port);    /* short, network byte order */
532  |         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
533  |         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
534  | 
535  |         if (connect(sockfd, (struct sockaddr *)&their_addr, 
536  |                                               sizeof(struct sockaddr)) == -1)
537  |         {
538  |             perror("connect");
539  |             exit(1);
540  |         }
541  |         if (send(sockfd, arg , strlen(arg), 0) == -1)
542  |                perror("send");
543  |         if (send(sockfd, "\n",1,0)  == -1)
544  |                perror("send");
545  | 
546  |         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0)
547  | 		{
548  |             buf[numbytes] = '\0';
549  |             if (result == NULL)
550  | 			{
551  |               result = strdup(buf);
552  |             }
553  | 			else
554  | 			{
555  |               result = (char *)realloc(result, strlen(result) + strlen(buf) + 1);
556  |               result = strcat(result, buf);
557  |             }
558  |         }
559  | 
560  |         close(sockfd);
561  |         return result;
562  | }
563  | 
564  | 
565  | 
566  | /* counts the number of objects in a string */
567  | int count_objects(char * arg)
568  | {
569  |     int count = 0;
570  |     char *pos = NULL;
571  |     char *temp = NULL;
572  | 
573  |     if(tracing) 
574  | 	{
575  |       printf("TRACING: count_objects running\n");
576  |     }
577  |     
578  |     if(arg != NULL)
579  | 	{
580  |       temp = strdup(arg);
581  |     }
582  | 	else
583  | 	{
584  |       return 0;
585  |     }
586  |     
587  |     if ( isalpha( (int)(arg[0]) ) )
588  | 	{
589  |       count++;
590  |     }
591  | 	else if (arg[0] == '\n' && isalpha( (int)(arg[1]) ) )
592  | 	{
593  |       count++;
594  |     }
595  |     while ( (pos = strstr(temp,"\n\n")) )
596  | 	{
597  |       pos[0] = 'a'; /* something non-EOL so that it won't be caught in the next loop */
598  |       if ( isalpha( (int)(pos[2]) ) )
599  | 	  {
600  |         count++;
601  |       }
602  |     }
603  |     if(tracing) 
604  | 	{
605  |       printf("TRACING: count_objects returning %d\n", count);
606  |     }
607  |     free(temp);
608  |     return count;
609  | }
610  | 
611  | 
612  | 
613  | /* strips lines beginning with '%' off  */
614  | char * strip_lines(char * arg)
615  | {
616  |     char ** temp = NULL;
617  |     char * string = NULL;
618  |     int i;
619  | 
620  |     if (arg == NULL)
621  | 	{
622  |        return NULL;
623  |     }
624  | 
625  |     /* split the string into lines */
626  |     temp = g_strsplit (arg, "\n", 0);
627  | 
628  |     for (i=0; temp[i] != NULL; i++)
629  | 	{
630  |       if (temp[i][0] != '%')
631  | 	  {
632  |         if (string == NULL)
633  | 		{
634  |           string = strdup(temp[i]);
635  |         }
636  | 		else
637  | 		{
638  |           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
639  |           string = strcat(string, "\n");
640  |           string = strcat(string, temp[i]);
641  |         }
642  |       }
643  |     }
644  |     return string;
645  | }
646  | 
647  | 
648  | /* Separates the objects in the given char * arg using "\n\n" as
649  |    separator. Returns a linked list whose data consist of separated
650  |    objects as  char *  */
651  | 
652  | GList * take_objects(char * arg)
653  | {
654  |     char ** objects=NULL;
655  |     char ** temp = NULL;
656  |     char * temp_object;
657  |     GList * tobereturned = NULL;
658  |     int i;
659  | 
660  |     arg = strip_lines(arg);
661  | 
662  |     objects =  g_strsplit(arg, "\n\n", 1000);
663  |     temp = objects;
664  |     for (i=0; temp[i] != NULL; i++)
665  | 	{
666  |       /* strip off the trailing and leading white spaces-eols*/
667  |       g_strstrip(temp[i]);
668  |       if (strlen(temp[i]) > 0)
669  | 	  { /* if not an empty string */
670  |         /* here we must add a "\n" at the end of the object, since RAToolSet parser can't
671  |           find the last attrib otherwise */
672  |         temp_object = (char *)malloc(strlen(temp[i]) + 2);
673  |         snprintf(temp_object, strlen(temp[i]) + 2, "%s\n", temp[i]);  
674  |         tobereturned = g_list_append(tobereturned, temp_object);
675  |       }
676  |     }
677  |     return tobereturned;
678  | }
679  | 
680  | 
681  | 
682  | /* takes the first object in the given char *, using empty lines as
683  |    separator */
684  | char * take_object(char * arg)
685  | {
686  |     GList * objects;
687  |     char * object;
688  | 
689  |     objects = take_objects(arg);
690  |     if (g_list_length(objects) > 0)
691  | 	{
692  |       object = strdup((char *)(g_list_nth_data(objects, 0)));
693  |     }
694  | 	else
695  | 	{
696  |       return NULL;
697  |     }
698  |     g_list_free(objects);
699  | 
700  |     return object;
701  | }
702  | 
703  | 
704  | 
705  | /* Takes an autnum_object, and returns the as-block containing this aut-num */
706  | char * get_as_block(rpsl_object_t *autnum_object)
707  | {
708  |   char * search_key = NULL, * query_string = NULL;
709  |   char * result = NULL;
710  |   char *return_value = NULL;
711  |   
712  |   search_key = get_search_key(autnum_object,"aut-num");
713  |   
714  |   query_string = (char *)malloc(strlen("-Tas-block -s  -r ")+strlen(current_source)+strlen(search_key)+1);
715  |   sprintf(query_string, "-Tas-block -s %s -r %s", current_source,search_key);
716  |   result = send_and_get(query_host, query_port, query_string);
717  |   free(query_string);
718  | 
719  |   if (count_objects(result) == 0)
720  |   {
721  |     if (tracing)
722  | 	{
723  |       printf("No such as-block\n"); 
724  |     }
725  | 	free(result);
726  |     return NULL;
727  |   }
728  |   else if (count_objects(result) > 1)
729  |   {
730  |     if (tracing)
731  | 	{
732  |       printf("More than one as-block returned\n");
733  |     }
734  | 	free(result);
735  |     return NULL;
736  |   }
737  |   else
738  |   { /* count_objects(result) == 1 */
739  |     return_value = take_object(result);
740  | 	free(result);
741  |     return return_value;
742  |   }
743  | }
744  | 
745  | 
746  | /* Takes a route_object, and returns the aut-num mentioned in origin
747  |    attribute of this route */
748  | char * get_aut_num_object(rpsl_object_t *route_object)
749  | {
750  |   char * search_key = NULL, * query_string = NULL;
751  |   char * result = NULL;
752  |   char *return_value = NULL;
753  |   
754  |   search_key = get_search_key(route_object,"origin");
755  |   
756  |   query_string = (char *)malloc(strlen("-Taut-num -s  -r ")+strlen(current_source)+strlen(search_key)+1);
757  |   sprintf(query_string, "-Taut-num -s %s -r %s", current_source,search_key);
758  |   result = send_and_get(query_host, query_port, query_string);
759  |   free(query_string);
760  | 
761  |   if (count_objects(result) == 0)
762  |   {
763  |     if (tracing)
764  | 	{
765  |       printf("No such aut-num\n");
766  |     }
767  | 	free(result);
768  |     return NULL;
769  |   }
770  |   else if (count_objects(result) > 1)
771  |   {
772  |     if (tracing)
773  | 	{
774  |       printf("More than one aut-num returned\n");
775  |     }
776  | 	free(result);
777  |     return NULL;
778  |   }
779  |   else
780  |   { /* count_objects(result) == 1 */
781  |     return_value = take_object(result);
782  | 	free(result);
783  |     return return_value;
784  |   }
785  | }
786  | 
787  | 
788  | 
789  | /* Takes a parsed domain_object, and returns the less specific domain of it */
790  | char * get_less_specific_domain(rpsl_object_t *domain_object)
791  | {
792  |   char *query_string = NULL;
793  |   char *result = NULL, *domain = NULL;
794  |   char *return_value = NULL;
795  |   int i,j, length;
796  |   char *temp = NULL;
797  |   char **splitted;
798  | 
799  |   domain = get_search_key(domain_object,"domain");
800  | 
801  |   /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
802  |   splitted =   g_strsplit((char *)strdup(domain), ".", 50);
803  | 
804  |   for (i=1; splitted[i] != NULL; i++)
805  |   {
806  |     /* in the following for loop, we will construct the 'less spec' domains
807  |        to be looked up in the DB */ 
808  |     for (j=i; splitted[j] !=NULL; j++)
809  | 	{
810  |       if (j==i)
811  | 	  {
812  |         temp = (char *)strdup(splitted[j]);
813  |       }
814  | 	  else
815  | 	  {
816  |         length = strlen(temp); 
817  |     	temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2); 
818  | 		strcat(temp, ".");
819  | 		strcat(temp, splitted[j]);
820  |       }
821  |     }
822  | 
823  |     query_string = (char *)malloc( strlen("-Tdomain -s  -r -R ")+strlen(current_source)+strlen(temp)+1 );
824  |     sprintf(query_string, "-Tdomain -s %s -r -R %s", current_source,temp);
825  |     result = send_and_get(query_host, query_port, query_string);
826  |     free(query_string);
827  | 	free(temp);
828  | 
829  |     if (count_objects(result) == 0)
830  | 	{
831  | 	  /* do nothing */
832  | 	  free(result);
833  |     }
834  | 	else if (count_objects(result) > 1)
835  | 	{
836  |       if (tracing)
837  | 	  {
838  |         printf("TRACING: get_less_specific_domain: More than one domains returned\n");
839  |       }
840  | 	  free(result);
841  |       return NULL; /* error condition */
842  |     }
843  | 	else
844  | 	{ /* count_objects(result) == 1 */
845  |       return_value = take_object(result);
846  | 	  free(result);
847  |       return return_value;
848  |     }
849  |   }
850  |   g_strfreev(splitted);
851  | 
852  |   /* so, we couldn't  find any 'less specific' domain */
853  |   return NULL;
854  | }
855  | 
856  | 
857  | 
858  | /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
859  |    by striping down the object's name ( eg, for as35:rs-trial:rs-myset, 
860  |    as35:rs-trial is tried ) */
861  | char * get_less_specific_set(rpsl_object_t *set_object, const char *type)
862  | {
863  |   char *search_key = NULL, *query_string = NULL;
864  |   char *result = NULL;
865  |   char *return_value = NULL;
866  |   int i;
867  |   
868  |   search_key = get_search_key(set_object, type);
869  | 
870  |   for (i = strlen(search_key) -1; i > -1; i--)
871  |   {
872  |     if (search_key[i] == ':')
873  | 	{
874  |       search_key[i] = '\0'; /* truncate the string */
875  |       break;
876  |     }
877  |     if (i == 0)
878  | 	{ /* if we've reached the beginning of the string 
879  |       (this means there wasn't any ';' in the string) */
880  |       free(search_key);
881  |       search_key = NULL;
882  |     }
883  |   }
884  |   if ( search_key == NULL || strlen(search_key) == 0)
885  |   { /* this mustn't happen in fact, since 
886  |     we make sure that the name of the 
887  |     set_object contains a ':' in a proper place */
888  |     return NULL;
889  |   }
890  |    
891  |   query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set,route-set -s  -r ") 
892  |            + strlen(current_source) + strlen(search_key) + 1);
893  |   sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set,route-set -s %s -r %s", current_source,search_key);
894  |   result = send_and_get(query_host, query_port, query_string);
895  |   free(search_key);
896  |   free(query_string);
897  | 
898  |   if (count_objects(result) == 0)
899  |   {
900  |     if (tracing)
901  |     {
902  |       printf("get_less_specific_set: No such object\n");
903  | 	}
904  | 	free(result);
905  |     return NULL;
906  |   }
907  |   else if (count_objects(result) > 1)
908  |   {
909  |     if (tracing)
910  |     {
911  |       printf("get_less_specific_set: More than one objects returned\n");
912  | 	}
913  | 	free(result);
914  |     return NULL;
915  |   }
916  |   else
917  |   { /* count_objects(result) == 1 */
918  |     return_value = take_object(result);
919  | 	free(result);
920  |     return return_value;
921  |   }
922  | }
923  | 
924  | 
925  | 
926  | /* Takes an inetnum or inet6num object and returns one more/less specific of it */
927  | char * get_specific(rpsl_object_t *inetnum_object, const char *type, char *flag)
928  | {
929  |   char *search_key = NULL, *query_string = NULL;
930  |   char *result = NULL;
931  |   char *return_value = NULL;
932  |   
933  |   search_key = get_search_key(inetnum_object, type);
934  |   
935  |   query_string = (char *)malloc(strlen("-Tinet6num  -s  -r  ")+strlen(current_source) + strlen(flag) + strlen(search_key) + 1);
936  |   sprintf(query_string, "-T%s -s %s -r %s %s",type, current_source, flag, search_key);
937  |   result = send_and_get(query_host, query_port, query_string);
938  |   free(search_key);
939  |   free(query_string);
940  | 
941  |   if (count_objects(result) == 0)
942  |   {
943  |     if (tracing)
944  |       printf("TRACING: get_specific: No %s %s returned\n", flag, type);
945  | 	free(result);
946  |     return NULL;
947  |   }
948  | /*  else if (count_objects(result) > 1)
949  |   {
950  |     if (tracing)
951  |       printf("TRACING: get_specific: More than one %s %s returned\n", flag, type);
952  | 	free(result);
953  |     return NULL;
954  |   }   */
955  |   else
956  |   { /* count_objects(result) >= 1 */
957  |     return_value = take_object(result);
958  | 	free(result);
959  |     return return_value;
960  |   }
961  | }
962  | 
963  | 
964  | 
965  | /* Takes a parsed route object and returns one less specific inetnum */
966  | char * get_less_spec_inetnum(rpsl_object_t *route_object)
967  | {
968  |   char * search_key = NULL, * query_string = NULL;
969  |   char * result = NULL;
970  |   char * return_value = NULL;
971  |   
972  |   search_key = get_search_key(route_object, "route");
973  |   
974  |   query_string = (char *)malloc(strlen("-Tinetnum -s  -r -l ")+strlen(current_source) + strlen(search_key) + 1);
975  |   sprintf(query_string, "-Tinetnum -s %s -r -l %s", current_source,search_key);
976  |   result = send_and_get(query_host, query_port, query_string);
977  |   free(search_key);
978  |   free(query_string);
979  | 
980  |   if (count_objects(result) == 0)
981  |   {
982  |     if (tracing)
983  | 	{
984  |       printf("get_less_spec_inetnum: No such inetnum\n");
985  | 	}
986  | 	free(result);
987  |     return NULL;
988  |   }
989  |   else if (count_objects(result) > 1)
990  |   {
991  |     if (tracing)
992  | 	{
993  |       printf("get_less_spec_inetnum: More than one inetnums returned\n");
994  | 	}
995  | 	free(result);
996  |     return NULL;
997  |   }
998  |   else
999  |   { /* count_objects(result) == 1 */
1000 |     return_value = take_object(result);
1001 | 	free(result);
1002 |     return return_value;
1003 |   }
1004 | }
1005 | 
1006 | 
1007 | /* Takes a parsed route object and returns exact match inetnum */
1008 | char * get_exact_match_inetnum(rpsl_object_t *route_object)
1009 | {
1010 |   char * search_key = NULL, * query_string = NULL;
1011 |   char * result = NULL;
1012 |   char * return_value = NULL;
1013 |   
1014 |   search_key = get_search_key(route_object, "route");
1015 |   
1016 |   query_string = (char *)malloc(strlen("-Tinetnum -s  -r -x ")+strlen(current_source) + strlen(search_key) + 1);
1017 |   sprintf(query_string, "-Tinetnum -s %s -r -x %s", current_source,search_key);
1018 |   result = send_and_get(query_host, query_port, query_string);
1019 |   free(search_key);
1020 |   free(query_string);
1021 | 
1022 |   if (count_objects(result) == 0)
1023 |   {
1024 |     if (tracing)
1025 | 	{
1026 |       printf("get_exact_match_inetnum: No such inetnum\n");
1027 | 	}
1028 | 	free(result);
1029 |     return NULL;
1030 |   }
1031 |   else if (count_objects(result) > 1)
1032 |   {
1033 |     if (tracing)
1034 | 	{
1035 |       printf("get_exact_match_inetnum: More than one inetnums returned\n");
1036 | 	}
1037 | 	free(result);
1038 |     return NULL;
1039 |   }
1040 |   else
1041 |   { /* count_objects(result) == 1 */
1042 |     return_value = take_object(result);
1043 | 	free(result);
1044 |     return return_value;
1045 |   }
1046 | }
1047 | 
1048 | 
1049 | 
1050 | /* Takes a route object and returns exact matches of this route */
1051 | GList *get_exact_match_routes(rpsl_object_t *route_object)
1052 | {
1053 |   char *search_key = NULL, *query_string = NULL;
1054 |   char *result = NULL;
1055 |   GList * return_value = NULL;
1056 |   
1057 |   search_key = get_search_key(route_object, "route");
1058 |   
1059 |   query_string = (char *)malloc(strlen("-Troute -s  -r -x ")+strlen(current_source) + strlen(search_key) + 1);
1060 |   sprintf(query_string, "-Troute -s %s -r -x %s", current_source,search_key);
1061 |   result = send_and_get(query_host, query_port, query_string);
1062 |   free(search_key);
1063 |   free(query_string);
1064 | 
1065 |   if (count_objects(result) == 0)
1066 |   {
1067 |     if (tracing)
1068 | 	{
1069 |       printf("get_exact_match_routes: No such route\n");
1070 | 	}
1071 | 	free(result);
1072 |     return NULL;
1073 |   }
1074 |   else
1075 |   { /* count_objects(result) >= 1 */
1076 |     return_value = take_objects(result);
1077 | 	free(result);
1078 |     return return_value;
1079 |   }
1080 | }
1081 | 
1082 | 
1083 | 
1084 | /* Takes a route object and returns (immediate) less specifics of this route */
1085 | GList *get_less_spec_routes(rpsl_object_t *route_object)
1086 | {
1087 |   char *search_key = NULL, *query_string = NULL;
1088 |   char *result = NULL;
1089 |   GList * return_value = NULL;
1090 |   
1091 |   search_key = get_search_key(route_object, "route");
1092 |   
1093 |   query_string = (char *)malloc(strlen("-Troute -s  -r -l ")+strlen(current_source) + strlen(search_key) + 1);
1094 |   sprintf(query_string, "-Troute -s %s -r -l %s", current_source,search_key);
1095 |   result = send_and_get(query_host, query_port, query_string);
1096 |   free(search_key);
1097 |   free(query_string);
1098 | 
1099 |   if (count_objects(result) == 0)
1100 |   {
1101 |     if(tracing)
1102 | 	{
1103 |       printf("get_less_spec_routes: No such route\n");
1104 | 	}
1105 | 	free(result);
1106 |     return NULL;
1107 |   }
1108 |   else
1109 |   { /* count_objects(result) >= 1 */
1110 |     return_value = take_objects(result);
1111 | 	free(result);
1112 |     return return_value;
1113 |   }
1114 | }
1115 | 
1116 | 
1117 | 
1118 | /* Gets an object as a parsed structure and returns its 'mnt-by' attributes as a 
1119 |    GList (linked list)   */
1120 | 
1121 | GList *get_mntners(rpsl_object_t *object)
1122 | {
1123 |   GList *list_of_mntners = NULL;
1124 | 
1125 |   if(tracing)
1126 |   {
1127 |     printf("TRACING: get_mntners is running\n");
1128 |   }
1129 | 
1130 |   list_of_mntners = rpsl_object_get_attr(object, "mnt-by");
1131 | 
1132 |   rpsl_attr_split_multiple(&list_of_mntners);
1133 | 
1134 |   return list_of_mntners; 
1135 | }
1136 | 
1137 | 
1138 | 
1139 | /* Gets an object as a parsed structure and returns its 'mnt-irt' attributes as a 
1140 |    GList (linked list)   */
1141 | 
1142 | GList *get_irts(rpsl_object_t *object)
1143 | {
1144 |   GList *list_of_irts = NULL;
1145 | 
1146 |   if(tracing)
1147 |   {
1148 |     printf("TRACING: get_irts is running\n");
1149 |   }
1150 | 
1151 |   list_of_irts = rpsl_object_get_attr(object, "mnt-irt");
1152 |   rpsl_attr_split_multiple(&list_of_irts);
1153 | 
1154 |   return list_of_irts; 
1155 | }
1156 | 
1157 | 
1158 | 
1159 | /* Gets a GList of strings and returns 1 if one of them starts with substr, 0 otherwise */
1160 | int strstr_in_list(GList *list, const char *substr)
1161 | {
1162 |  GList * item = NULL;
1163 |  char * word; 
1164 | 
1165 |   if (tracing)
1166 |   {
1167 |     printf("TRACING: strstr_in_list is running\n");
1168 |   }
1169 |  
1170 |  for ( item = list; item != NULL ; item = g_list_next(item) )
1171 |  {
1172 |    word = strdup((char *)(item->data));
1173 |    g_strup(word);
1174 |    if (strstr(word, substr) == word)
1175 |    {
1176 |      free(word);
1177 |      return 1;
1178 |    }
1179 |    free(word);
1180 |  }
1181 |  /* none of them matched, so return 0 */
1182 |  return 0; 
1183 | }
1184 | 
1185 | /* Gets a GList of attr structures and returns 1 if one of their (upper case)values 
1186 |    starts with substr, otherwise returns 0 */
1187 | int strstr_in_attr_list(GList * list, const char * substr)
1188 | {
1189 |  GList * item = NULL;
1190 |  char * word; 
1191 | 
1192 |   if (tracing)
1193 |   {
1194 |     printf("TRACING: strstr_in_attr_list is running\n");
1195 |   }
1196 |  
1197 |  for( item = list; item != NULL ; item = g_list_next(item) )
1198 |  {
1199 |    word = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
1200 |    g_strup(word);
1201 |    if (strstr(word, substr) == word)
1202 |    {
1203 |      free(word);
1204 |      return 1;
1205 |    }
1206 |    free(word);
1207 |  }
1208 |  /* none of them matched, so return 0 */
1209 |  return 0; 
1210 | }
1211 | 
1212 | 
1213 | 
1214 | /* Gets a (maintainer/irt) object as a string and returns its 'auth' attributes 
1215 |    as a GList (linked list) */
1216 | 
1217 | GList *get_auths(char * object_str)
1218 | {
1219 |   const char *name = NULL;
1220 |   char *value = NULL;
1221 |   GList *attr;
1222 |   rpsl_object_t *object;
1223 |   GList *list_of_auths = NULL;
1224 | 
1225 |   if(tracing)
1226 |   {
1227 |     printf("TRACING: get_auths is running\n");
1228 |   }
1229 |   object = rpsl_object_init(object_str);
1230 |   
1231 |   list_of_auths = rpsl_object_get_attr(object, "auth");
1232 |   rpsl_attr_split_multiple(&list_of_auths);
1233 |   
1234 |   if(tracing) 
1235 |   {
1236 | 	if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1237 | 	{
1238 | 	  /* thre was an error during the parsing */
1239 | 	  name = rpsl_object_get_class(object);
1240 | 	  if ( name )
1241 | 	  {
1242 | 		attr = rpsl_object_get_attr(object, name);
1243 | 		if ( attr )
1244 | 		{
1245 | 		  value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1246 | 		  if ( value )
1247 | 		  {
1248 | 			printf("TRACING: get_auths: error parsing object %s\n", value );
1249 | 			free(value);
1250 | 		  }
1251 | 		  else
1252 | 			printf("TRACING: get_auths: error parsing object\n");
1253 | 
1254 | 		  rpsl_attr_delete_list(attr);
1255 | 		}
1256 | 	  }
1257 | 	}
1258 |     printf("TRACING: get_auths: returning (with %d nodes)\n", g_list_length(list_of_auths));
1259 |   }
1260 | 
1261 |   rpsl_object_delete(object);
1262 |   return list_of_auths; 
1263 | }
1264 | 
1265 | 
1266 | 
1267 | /* Gets a parsed object and returns its 'attr_type' attributes as a 
1268 |    GList (linked list) */
1269 | 
1270 | GList *get_attr_list(rpsl_object_t *object, const char *attr_type)
1271 | {
1272 |   GList *list_of_attrs = NULL;
1273 |   char *object_str = NULL;
1274 | 
1275 |   if (tracing)
1276 |   {
1277 |     object_str = rpsl_object_get_text(object,0);
1278 |     printf("TRACING: get_attr_list is running searching for %s, object is [\n%s]\n", attr_type ? attr_type : "NULL", object_str ? object_str : "NULL");
1279 |     free(object_str);
1280 |   }
1281 | 
1282 |   list_of_attrs = rpsl_object_get_attr(object, attr_type);
1283 |   rpsl_attr_split_multiple(&list_of_attrs);
1284 | 
1285 |   return list_of_attrs; 
1286 | }
1287 | 
1288 | 
1289 | 
1290 | /* Gets a parsed object and returns its mnt_lower attributes as a 
1291 |    GList (linked list) */
1292 | 
1293 | GList *get_mnt_lowers(rpsl_object_t *object)
1294 | {
1295 |   GList *list_of_mnt_lowers = NULL;
1296 | 
1297 |   if (tracing)
1298 |   {
1299 |     printf("TRACING: get_mnt_lowers is running\n");
1300 |   }
1301 | 
1302 |   list_of_mnt_lowers = rpsl_object_get_attr(object, "mnt-lower");
1303 |   rpsl_attr_split_multiple(&list_of_mnt_lowers);
1304 |   
1305 |   return list_of_mnt_lowers; 
1306 | }
1307 | 
1308 | 
1309 | /* Gets a parsed object and returns its mnt_routes attributes as a 
1310 |    GList (linked list) */
1311 | 
1312 | GList *get_mnt_routes(rpsl_object_t *object)
1313 | {
1314 |   GList *list_of_mnt_routes = NULL;
1315 | 
1316 |   if (tracing)
1317 |   {
1318 |     printf("TRACING: get_mnt_routes is running\n");
1319 |   }
1320 | 
1321 |   list_of_mnt_routes = rpsl_object_get_attr(object, "mnt-routes");
1322 |   rpsl_attr_split_multiple(&list_of_mnt_routes );
1323 | 
1324 |   return list_of_mnt_routes; 
1325 | }
1326 | 
1327 | 
1328 | /* Gets a linked list of object strings and returns the mnt_routes attribs of
1329 |    them in a linked list */
1330 | GList *get_mnt_routes_from_list(GList *objects_str)
1331 | {
1332 |   GList *objects_str_item = NULL;
1333 |   GList *list_of_mnt_routes = NULL;
1334 |   const char *name = NULL;
1335 |   char *value = NULL;
1336 |   GList *attr;
1337 |   rpsl_object_t *object;
1338 |   
1339 |   for ( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
1340 |   {
1341 | 	object = rpsl_object_init((char *)(objects_str_item->data));
1342 | 
1343 | 	if (tracing)
1344 | 	{
1345 |       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1346 | 	  {
1347 | 		/* thre was an error during the parsing */
1348 | 		name = rpsl_object_get_class(object);
1349 | 		if ( name )
1350 | 		{
1351 | 		  attr = rpsl_object_get_attr(object, name);
1352 | 		  if ( attr )
1353 | 		  {
1354 | 		    value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1355 | 			if ( value )
1356 | 			{
1357 | 		      printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
1358 | 			  free(value);
1359 | 			}
1360 | 			else
1361 | 		      printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
1362 | 
1363 | 			rpsl_attr_delete_list(attr);
1364 | 		  }
1365 | 		}
1366 | 	  }
1367 | 	}
1368 | 
1369 |     list_of_mnt_routes = g_list_concat(list_of_mnt_routes, get_mnt_routes(object));
1370 |     rpsl_object_delete(object);
1371 |   }
1372 | 
1373 |   return list_of_mnt_routes;
1374 | }
1375 | 
1376 | 
1377 | /* Gets a linked list of object strings and returns the mnt_lowers attribs of
1378 |    them in a linked list */
1379 | GList *get_mnt_lowers_from_list(GList * objects_str)
1380 | {
1381 |   GList *objects_str_item = NULL;
1382 |   GList *list_of_mnt_lowers = NULL;
1383 |   const char *name = NULL;
1384 |   char *value = NULL;
1385 |   GList *attr;
1386 |   rpsl_object_t *object;
1387 |   
1388 |   for( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
1389 |   {
1390 | 	object = rpsl_object_init((char *)(objects_str_item->data));
1391 | 
1392 | 	if (tracing)
1393 | 	{
1394 |       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1395 | 	  {
1396 | 		/* thre was an error during the parsing */
1397 | 		name = rpsl_object_get_class(object);
1398 | 		if ( name )
1399 | 		{
1400 | 		  attr = rpsl_object_get_attr(object, name);
1401 | 		  if ( attr )
1402 | 		  {
1403 | 		    value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1404 | 			if ( value )
1405 | 			{
1406 | 		      printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
1407 | 			  free(value);
1408 | 			}
1409 | 			else
1410 | 		      printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
1411 | 
1412 | 			rpsl_attr_delete_list(attr);
1413 | 		  }
1414 | 		}
1415 | 	  }
1416 | 	}
1417 | 
1418 |     list_of_mnt_lowers = g_list_concat(list_of_mnt_lowers, get_mnt_lowers(object));
1419 |     rpsl_object_delete(object);
1420 |   }
1421 | 
1422 |   return list_of_mnt_lowers;
1423 | }
1424 | 
1425 | 
1426 | /* Gets a linked list of object strings and returns the mnt-by attribs of
1427 |    them in a linked list */
1428 | GList *get_mntners_from_list(GList *objects_str)
1429 | {
1430 |   GList *objects_str_item = NULL;
1431 |   GList *list_of_mntners = NULL;
1432 |   const char *name = NULL;
1433 |   char *value = NULL;
1434 |   GList *attr;
1435 |   rpsl_object_t *object;
1436 |   
1437 |   for ( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
1438 |   {
1439 | 	object = rpsl_object_init((char *)(objects_str_item->data));
1440 | 
1441 | 	if (tracing)
1442 | 	{
1443 |       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
1444 | 	  {
1445 | 		/* thre was an error during the parsing */
1446 | 		name = rpsl_object_get_class(object);
1447 | 		if ( name )
1448 | 		{
1449 | 		  attr = rpsl_object_get_attr(object, name);
1450 | 		  if ( attr )
1451 | 		  {
1452 | 		    value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
1453 | 			if ( value )
1454 | 			{
1455 | 		      printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
1456 | 			  free(value);
1457 | 			}
1458 | 			else
1459 | 		      printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
1460 | 
1461 | 			rpsl_attr_delete_list(attr);
1462 | 		  }
1463 | 		}
1464 | 	  }
1465 | 	}
1466 | 
1467 |     list_of_mntners = g_list_concat(list_of_mntners, get_mntners(object));
1468 |     rpsl_object_delete(object);
1469 |   }
1470 | 
1471 |   return list_of_mntners;
1472 | }
1473 | 
1474 | 
1475 | 
1476 | /* retrieves the override password from the 'override' attribute  
1477 |    of the object. If none, it returns NULL   */
1478 | char *get_override(rpsl_object_t * object)
1479 | {
1480 | 
1481 |   GList *attr_list;
1482 | 
1483 |   if(tracing)
1484 |   {
1485 |     printf("TRACING: get_override is running\n");
1486 |   }
1487 |   
1488 |   attr_list = rpsl_object_get_attr(object, "override");
1489 |   if ( ! attr_list )
1490 |   {
1491 |     /* there was no 'override' attrib, so return NULL */
1492 |     return NULL;
1493 |   }
1494 | 
1495 |   /* there should only be one item in this list, 
1496 |      return the clean value of that attribute */
1497 |   return strdup(rpsl_attr_get_value((rpsl_attr_t *)(attr_list->data)));
1498 | }
1499 | 
1500 | 
1501 | 
1502 | /* checks override string (password) 
1503 |    returns OVR_OK if it is correct password */
1504 | int check_override(char * string)
1505 | {
1506 |    char ** temp;
1507 |    int i;
1508 |    char * crypted_password = strdup(overridecryptedpw);
1509 | 
1510 |    if(string == NULL) 
1511 |    {
1512 |      if(tracing) 
1513 | 	 {
1514 |        printf("TRACING: check_override is returning FAILED\n");
1515 |      }
1516 | 	 free (crypted_password);
1517 |      return UP_OVF; /* override attempt failed */ 
1518 |    }
1519 |    else
1520 |    {
1521 |     /* split the string */
1522 |      temp = g_strsplit (string, " ", 0);
1523 | 
1524 |      for(i=0; temp[i] != NULL; i++)
1525 | 	 {
1526 |        if(strlen(temp[i]) != 0)
1527 | 	   {
1528 |          if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0)
1529 | 		 {
1530 |            if(tracing) 
1531 | 		   {
1532 |              printf("TRACING: check_override is returning %s OK\n", string);
1533 |            }
1534 |            g_strfreev(temp);
1535 | 		   free (crypted_password);
1536 |            return OVR_OK; 
1537 |          }
1538 |        }
1539 |      }
1540 | 
1541 |      /* we couldn't find a word matching the override password */ 
1542 |      g_strfreev(temp);         
1543 | 	 free (crypted_password);
1544 |      return UP_OVF; /* override attempt failed */
1545 |    }
1546 | }
1547 | 
1548 | 
1549 | 
1550 | 
1551 | /* takes a GSList of struct auth_struct and a GList of auths, and a mntner/irt name,
1552 |    add new elements to GSList of struct auth_struct and  returns the new
1553 |    GSList of struct auth_struct  */
1554 | 
1555 | GSList * add_to_auth_vector(GSList * list_of_auth_struct, GList * auths, char * mntner_name)
1556 | {
1557 |    GList * auth_item;
1558 |    char * auth_attrib = NULL;
1559 |    char * auth_attrib_uppercase = NULL, * argument = NULL;
1560 |    auth_struct * temp = NULL;
1561 |    int index = 1;
1562 |    
1563 |    for (auth_item = auths; auth_item != NULL; auth_item = g_list_next(auth_item))
1564 |    {
1565 |      auth_attrib = rpsl_attr_get_clean_value((rpsl_attr_t *)(auth_item->data));
1566 |      if(tracing)
1567 | 	 {
1568 |        printf("TRACING: add_to_auth_vector: %s\n", auth_attrib);
1569 |      }
1570 |      /* Take the auth attribute and convert it into uppercase for comparisons */
1571 |      auth_attrib_uppercase = strdup(auth_attrib);
1572 |      g_strup(auth_attrib_uppercase);
1573 |      
1574 |      if ( strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase )
1575 | 	 {
1576 |        /* take the argument of the auth attribute */
1577 |        argument = strdup(auth_attrib + strlen("CRYPT-PW"));
1578 |        g_strstrip(argument);
1579 |        if(tracing) 
1580 | 	   {
1581 |          printf("TRACING: add_to_auth_vector: adding new CRYPT-PW argument: %s\n", argument);
1582 |        }
1583 |        temp = (auth_struct *)malloc(sizeof(auth_struct));
1584 |        temp->type = AU_CRYPT_PW;
1585 |        temp->auth = argument;
1586 |        temp->mntner_name = mntner_name;
1587 |        temp->index = index++;
1588 |        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1589 |      }
1590 |      else if ( strstr(auth_attrib_uppercase,"MD5-PW") == auth_attrib_uppercase )
1591 | 	 {
1592 |        /* take the argument of the auth attribute */
1593 |        argument = strdup(auth_attrib + strlen("MD5-PW"));
1594 |        g_strstrip(argument);
1595 |        if(tracing) 
1596 | 	   {
1597 |          printf("TRACING: add_to_auth_vector: adding new MD5-PW argument: %s\n", argument);
1598 |        }
1599 |        temp = (auth_struct *)malloc(sizeof(auth_struct));
1600 |        temp->type = AU_MD5_PW;
1601 |        temp->auth = argument;
1602 |        temp->mntner_name = mntner_name;
1603 |        temp->index = index++;
1604 |        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1605 |      }
1606 | 	 else if (strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase)
1607 | 	 {
1608 |        /* take the argument of the auth attribute */
1609 |        argument = strdup(auth_attrib + strlen("MAIL-FROM"));
1610 |        g_strstrip(argument);
1611 |        if(tracing)
1612 | 	   {
1613 |          printf("TRACING: add_to_auth_vector: adding new MAIL-FROM argument: %s\n", argument);
1614 |        }
1615 |        temp = (auth_struct *)malloc(sizeof(auth_struct));
1616 |        temp->type = AU_MAIL_FROM;
1617 |        temp->auth = argument;
1618 |        temp->mntner_name = mntner_name;
1619 |        temp->index = index++;
1620 |        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1621 |      }
1622 | 	 else if (strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase)
1623 | 	 {
1624 |        /* take the argument of the auth attribute */
1625 |        if(tracing)
1626 | 	   {
1627 |          printf("TRACING: add_to_auth_vector: adding new NONE argument\n");
1628 |        }
1629 |        temp = (auth_struct *)malloc(sizeof(auth_struct));
1630 |        temp->type = AU_NONE;
1631 |        temp->auth = NULL;
1632 |        temp->mntner_name = mntner_name;
1633 |        temp->index = index++;
1634 |        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1635 |     }
1636 | 	else if (strstr(auth_attrib_uppercase,"PGPKEY-") == auth_attrib_uppercase)
1637 | 	{
1638 |        argument = strdup(auth_attrib + strlen("PGPKEY-"));
1639 |        g_strstrip(argument);
1640 |        if(tracing)
1641 | 	   {
1642 |          printf("TRACING: add_to_auth_vector: adding new PGPKEY argument: %s\n", argument);
1643 |        }
1644 |        temp = (auth_struct *)malloc(sizeof(auth_struct));
1645 |        temp->type = AU_PGP;
1646 |        temp->mntner_name = mntner_name;
1647 |        temp->index = index++;
1648 |        temp->auth = argument;
1649 |        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1650 |      }
1651 | 	 else
1652 | 	 {
1653 |        if (tracing)
1654 | 	   {
1655 |          printf("TRACING: Error: invalid auth attrib: %s\n", auth_attrib);
1656 |        }
1657 |        return NULL;
1658 |      }
1659 |  
1660 |      free(auth_attrib_uppercase);
1661 |      free(auth_attrib); 
1662 |    }
1663 | 
1664 |    return list_of_auth_struct;
1665 | }
1666 | 
1667 | 
1668 | 
1669 | 
1670 | /* Gets a list of mntner names, retrieves those mntners from
1671 |    the database and extracts the 'auth' attributes, and
1672 |    constructs the authorisation vector, which is a GSList of
1673 |    struct auth_struct */
1674 | 
1675 | GSList * get_auth_vector(GList * mntners)
1676 | {
1677 |   GList * list_of_auths = NULL;
1678 |   GList * mntner_item = NULL;
1679 |   GSList * to_be_returned = NULL;
1680 |   char * query_string = NULL, * result = NULL, * object_str = NULL;
1681 |   char *value;
1682 | 
1683 |   for( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
1684 |   {
1685 |     value = rpsl_attr_get_clean_value((rpsl_attr_t *)(mntner_item->data));
1686 |     if(tracing) 
1687 | 	{
1688 |       printf("=====\nget_auth_vector: Got a mntner\n%s\n", value  );
1689 |     }
1690 |     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
1691 |     sprintf(query_string, "-Tmntner -s %s -r %s",current_source,value);
1692 |     result = send_and_get(query_host, query_port, query_string);
1693 | 	free(query_string);
1694 |     if (count_objects(result) == 0)
1695 | 	{
1696 |       /* no such maintainer */
1697 |       if(tracing)
1698 | 	  {
1699 |         printf("get_auth_vector: No such maintainer %s\n", value);
1700 |       }
1701 | 	  free(result);
1702 | 	  free(value);
1703 |       return NULL;
1704 |     }
1705 | 	else if (count_objects(result) > 1)
1706 | 	{
1707 |       if(tracing)
1708 | 	  {
1709 |         printf("get_auth_vector: More than one objects returned for %s\n", value);
1710 |       }
1711 |     }
1712 | 	else
1713 | 	{ /* count_objects(result) == 1 */
1714 |       object_str = take_object(result);
1715 |       if(tracing)
1716 | 	  {
1717 |         printf("TRACING: get_auth_vector: Calling get_auths with object [\n%s]\n", object_str);
1718 |       }
1719 | 
1720 |       list_of_auths = get_auths(object_str);
1721 |       if(tracing)
1722 | 	  {
1723 |         printf("TRACING: get_auth_vector: get_auths returned (with %d nodes)\n", g_list_length(list_of_auths)) ;
1724 |       }
1725 | 
1726 |       /* add this to the auth_vector. ( mntner_item->data->value is the name of the maintainer  ) */
1727 |       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)value);
1728 |       if(tracing)
1729 | 	  {
1730 |        printf("TRACING: get_auth_vector: to_be_returned has now %d nodes\n",  g_slist_length(to_be_returned));
1731 |       }
1732 | 	  
1733 | 	  rpsl_attr_delete_list(list_of_auths);
1734 |     }
1735 | 	free(value);
1736 | 	free(result);
1737 |   }
1738 |   
1739 |   if(tracing) 
1740 |   {  
1741 |     printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1742 |   }
1743 |   return to_be_returned; 
1744 | }
1745 | 
1746 | 
1747 | 
1748 | /* Gets a list of irt names, retrieves those irts from
1749 |    the database and extracts the 'auth' attributes, and
1750 |    constructs the authorisation vector, which is a GSList of
1751 |    struct auth_struct */
1752 | 
1753 | GSList * get_irt_auth_vector(GList * irts)
1754 | {
1755 |   GList * list_of_auths = NULL;
1756 |   GList * irt_item = NULL;
1757 |   GSList * to_be_returned = NULL;
1758 |   char * query_string = NULL, * result = NULL, * object_str = NULL;
1759 |   char *value;
1760 | 
1761 |   for( irt_item = irts; irt_item != NULL ; irt_item = g_list_next(irt_item) )
1762 |   {
1763 |     value = rpsl_attr_get_clean_value((rpsl_attr_t *)(irt_item->data));
1764 |     if(tracing) 
1765 | 	{
1766 |       printf("=====\nget_irt_auth_vector: Got an irt\n%s\n", value  );
1767 |     }
1768 |     query_string = (char *)malloc(strlen("-Tirt -s  -r ")+strlen(current_source)+strlen(value)+1);
1769 |     sprintf(query_string, "-Tirt -s %s -r %s",current_source,value);
1770 |     result = send_and_get(query_host, query_port, query_string);
1771 | 	free(query_string);
1772 |     if (count_objects(result) == 0)
1773 | 	{
1774 |       /* no such irt */
1775 |       if(tracing)
1776 | 	  {
1777 |         printf("get_irt_auth_vector: No such irt %s\n", value);
1778 |       }
1779 | 	  free(result);
1780 | 	  free(value);
1781 |       return NULL;
1782 |     }
1783 | 	else if (count_objects(result) > 1)
1784 | 	{
1785 |       if(tracing)
1786 | 	  {
1787 |         printf("get_irt_auth_vector: More than one objects returned for %s\n", value);
1788 |       }
1789 |     }
1790 | 	else
1791 | 	{ /* count_objects(result) == 1 */
1792 |       object_str = take_object(result);
1793 |       if(tracing)
1794 | 	  {
1795 |         printf("TRACING: get_irt_auth_vector: Calling get_auths with object [\n%s]\n", object_str);
1796 |       }
1797 | 
1798 |       list_of_auths = get_auths(object_str);
1799 |       if(tracing)
1800 | 	  {
1801 |         printf("TRACING: get_irt_auth_vector: get_auths returned (with %d nodes)\n", g_list_length(list_of_auths)) ;
1802 |       }
1803 | 
1804 |       /* add this to the auth_vector. ( irt_item->data->value is the name of the irt  ) */
1805 |       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)value);
1806 |       if(tracing)
1807 | 	  {
1808 |        printf("TRACING: get_irt_auth_vector: to_be_returned has now %d nodes\n",  g_slist_length(to_be_returned));
1809 |       }
1810 | 	  
1811 | 	  rpsl_attr_delete_list(list_of_auths);
1812 |     }
1813 | 	free(value);
1814 | 	free(result);
1815 |   }
1816 |   
1817 |   if(tracing) 
1818 |   {  
1819 |     printf("TRACING: get_irt_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1820 |   }
1821 |   return to_be_returned; 
1822 | }
1823 | 
1824 | 
1825 | 
1826 | 
1827 | /* Gets a list of mntner attributes, retrieves those mntners from
1828 |    the database and extracts the 'mnt-nfy' attributes, and
1829 |    returns them as a GList */
1830 | 
1831 | GList * get_mntnfy_vector(GList *mntners)
1832 | {
1833 |   GList * list_of_mntnfy = NULL;
1834 |   GList * mntner_item = NULL;
1835 |   GList * temp;
1836 |   const GList * error_list = NULL;
1837 |   char * query_string = NULL, * result = NULL, * object_str = NULL;
1838 |   char *value;
1839 |   rpsl_object_t *object;
1840 |   
1841 |   for ( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
1842 |   {
1843 | 	value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(mntner_item->data) );
1844 |     if (tracing)
1845 | 	{
1846 |       printf( "=====\nGot a mntner\n%s\n", value );
1847 |     }
1848 |     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
1849 |     sprintf(query_string, "-Tmntner -s %s -r %s", current_source,value);
1850 |     result = send_and_get(query_host, query_port, query_string);
1851 | 	free(query_string);
1852 |     if (count_objects(result) == 0)
1853 | 	{
1854 |       /* no such maintainer */
1855 |       if(tracing)
1856 | 	  {
1857 |         printf("get_mntnfy_vector: No such maintainer %s\n", value);
1858 |       }
1859 |     }
1860 | 	else if (count_objects(result) > 1)
1861 | 	{
1862 |       if (tracing)
1863 | 	  {
1864 |         printf("get_mntnfy_vector: More than one objects returned for maintainer %s\n", value);
1865 |       }
1866 |     }
1867 | 	else
1868 | 	{ /* count_objects(result) == 1 */
1869 |       object_str = take_object(result);
1870 | 	  object = rpsl_object_init(object_str);
1871 | 	  error_list = rpsl_object_errors(object);
1872 | 
1873 |       if (tracing)
1874 | 	  {
1875 |         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1876 |       }
1877 | 
1878 |       temp = get_attr_list(object, "mnt-nfy");
1879 | 
1880 |       if (tracing)
1881 | 	  {
1882 |         printf("TRACING: get_mntnfy_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
1883 |       }
1884 | 
1885 |       list_of_mntnfy = g_list_concat(list_of_mntnfy, temp);
1886 | 
1887 |       if (tracing)
1888 | 	  {
1889 |         printf("TRACING: get_mntnfy_vector: list_of_mntnfy has now %i nodes\n", g_list_length(list_of_mntnfy));
1890 |       }
1891 |       rpsl_object_delete(object);
1892 |     }
1893 | 	free(value);
1894 | 	free(result);
1895 |   }
1896 |   
1897 |   if (tracing)
1898 |   {  
1899 |     printf("TRACING: get_mntnfy_vector: list_of_mntnfy has %i nodes\n", g_list_length(list_of_mntnfy)); 
1900 |   }
1901 |   return list_of_mntnfy; 
1902 | }
1903 | 
1904 | 
1905 | 
1906 | 
1907 | /* Gets a list of irt attributes, retrieves those irts from
1908 |    the database and extracts the 'irt-nfy' attributes, and
1909 |    returns them as a GList */
1910 | 
1911 | GList * get_irtnfy_vector(GList *irts)
1912 | {
1913 |   GList * list_of_irtnfy = NULL;
1914 |   GList * irt_item = NULL;
1915 |   GList * temp;
1916 |   const GList * error_list = NULL;
1917 |   char * query_string = NULL, * result = NULL, * object_str = NULL;
1918 |   char *value;
1919 |   rpsl_object_t *object;
1920 |   
1921 |   for ( irt_item = irts; irt_item != NULL ; irt_item = g_list_next(irt_item) )
1922 |   {
1923 | 	value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(irt_item->data) );
1924 |     if (tracing)
1925 | 	{
1926 |       printf( "=====\nGot a irt\n%s\n", value );
1927 |     }
1928 |     query_string = (char *)malloc(strlen("-Tirt -s  -r ")+strlen(current_source)+strlen(value)+1);
1929 |     sprintf(query_string, "-Tirt -s %s -r %s", current_source,value);
1930 |     result = send_and_get(query_host, query_port, query_string);
1931 | 	free(query_string);
1932 |     if (count_objects(result) == 0)
1933 | 	{
1934 |       /* no such irt */
1935 |       if(tracing)
1936 | 	  {
1937 |         printf("get_irtnfy_vector: No such irt %s\n", value);
1938 |       }
1939 |     }
1940 | 	else if (count_objects(result) > 1)
1941 | 	{
1942 |       if (tracing)
1943 | 	  {
1944 |         printf("get_irtnfy_vector: More than one objects returned for irt %s\n", value);
1945 |       }
1946 |     }
1947 | 	else
1948 | 	{ /* count_objects(result) == 1 */
1949 |       object_str = take_object(result);
1950 | 	  object = rpsl_object_init(object_str);
1951 | 	  error_list = rpsl_object_errors(object);
1952 | 
1953 |       if (tracing)
1954 | 	  {
1955 |         printf("TRACING: get_irtnfy_vector: Calling get_attr_list\n");
1956 |       }
1957 | 
1958 |       temp = get_attr_list(object, "irt-nfy");
1959 | 
1960 |       if (tracing)
1961 | 	  {
1962 |         printf("TRACING: get_irtnfy_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
1963 |       }
1964 | 
1965 |       list_of_irtnfy = g_list_concat(list_of_irtnfy, temp);
1966 | 
1967 |       if (tracing)
1968 | 	  {
1969 |         printf("TRACING: get_irtnfy_vector: list_of_irtnfy has now %i nodes\n", g_list_length(list_of_irtnfy));
1970 |       }
1971 |       rpsl_object_delete(object);
1972 |     }
1973 | 	free(value);
1974 | 	free(result);
1975 |   }
1976 |   
1977 |   if (tracing)
1978 |   {  
1979 |     printf("TRACING: get_irtnfy_vector: list_of_irtnfy has %i nodes\n", g_list_length(list_of_irtnfy)); 
1980 |   }
1981 |   return list_of_irtnfy; 
1982 | }
1983 | 
1984 | 
1985 | 
1986 | /* Gets a list of mntner names, retrieves those mntners from
1987 |    the database and extracts the 'upd-to' attributes, and
1988 |    returns them as a GList */
1989 | 
1990 | GList * get_updto_vector(GList * mntners)
1991 | {
1992 |   GList * list_of_updto = NULL;
1993 |   GList * mntner_item = NULL;
1994 |   char * query_string = NULL, * result = NULL, * object_str = NULL;
1995 |   GList * temp;
1996 |   const GList * error_list = NULL;
1997 |   char *value;
1998 |   rpsl_object_t *object;
1999 |   
2000 |   for ( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
2001 |   {
2002 | 	value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(mntner_item->data) );
2003 |     if (tracing)
2004 | 	{
2005 |       printf( "=====\nGot a mntner\n%s\n", value );
2006 |     }
2007 |     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
2008 |     sprintf(query_string, "-Tmntner -s %s -r %s", current_source,value);
2009 |     result = send_and_get(query_host, query_port, query_string);
2010 |     if (count_objects(result) == 0)
2011 | 	{
2012 |       /* no such maintainer */
2013 |       if(tracing)
2014 | 	  {
2015 |         printf("get_updto_vector: No such maintainer %s\n", value);
2016 |       }
2017 |     }
2018 | 	else if(count_objects(result) > 1)
2019 | 	{
2020 |       if (tracing)
2021 | 	  {
2022 |         printf("get_updto_vector: More than one objects returned for maintainer %s\n", value);
2023 |       }
2024 |     }
2025 | 	else
2026 | 	{ /* count_objects(result) == 1 */
2027 |       object_str = take_object(result);
2028 | 	  object = rpsl_object_init(object_str);
2029 | 	  error_list = rpsl_object_errors(object);
2030 | 
2031 |       if (tracing)
2032 | 	  {
2033 |         printf("TRACING: get_updto_vector: Calling get_attr_list\n");
2034 |       }
2035 | 
2036 |       temp = get_attr_list(object, "upd-to");
2037 | 
2038 |       if (tracing)
2039 | 	  {
2040 |         printf("TRACING: get_updto_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
2041 |       }
2042 | 
2043 |       list_of_updto = g_list_concat(list_of_updto, temp);
2044 | 
2045 |       if (tracing)
2046 | 	  {
2047 |         printf("TRACING: get_updto_vector: list_of_mntnfy has now %i nodes\n",  g_list_length(list_of_updto));
2048 |       }
2049 |       rpsl_object_delete(object);
2050 |     }
2051 | 	free(value);
2052 | 	free(result);
2053 |   }
2054 |   
2055 |   if (tracing)
2056 |   {  
2057 |     printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_list_length(list_of_updto)); 
2058 |   }
2059 |   return list_of_updto; 
2060 | }
2061 | 
2062 | 
2063 | 
2064 | 
2065 | /* gets one or more route objects filters out the ones which don't have the same
2066 |    origin as 'char * origin' argument */
2067 | char * up_filter_out_diff_origins(char * objects_str, char * origin)
2068 | {
2069 |   GList * object_str_list = NULL, * object_str_item =NULL;
2070 |   const GList *error_list = NULL; 
2071 |   char * objects_to_be_returned = NULL;
2072 |   char * key = NULL;
2073 |   rpsl_object_t *object;
2074 |   
2075 |   if (tracing) 
2076 |   {
2077 |     printf("TRACING: up_filter_out_diff_origins\n");
2078 |   }
2079 | 
2080 |   /* strip the lines beginning with '%' off */
2081 |   objects_str = strip_lines(objects_str);
2082 |   
2083 |   /* separate the objects, store them in a linked list */
2084 |   object_str_list = take_objects(objects_str);
2085 | 
2086 |   for (object_str_item = object_str_list; object_str_item != NULL; object_str_item = g_list_next(object_str_item))
2087 |   {
2088 |     object = rpsl_object_init((char *)(object_str_item->data));
2089 | 	error_list = rpsl_object_errors(object);
2090 |     key = get_search_key(object, "origin");
2091 |     if (key != NULL && strcasecmp(g_strstrip(origin), key) == 0)
2092 | 	{
2093 |       if (objects_to_be_returned == NULL)
2094 | 	  {
2095 |         objects_to_be_returned = strdup((char *)(object_str_item->data));
2096 |       }
2097 | 	  else
2098 | 	  {
2099 |         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
2100 |                       strlen(objects_to_be_returned) + strlen((char *)(object_str_item->data)) + 2);
2101 |         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
2102 |         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_str_item->data));
2103 |       }
2104 |     }
2105 |     rpsl_object_delete(object);
2106 | 	free(key);
2107 |   }
2108 | 
2109 |   if(tracing) 
2110 |   {
2111 |       printf("TRACING: up_filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned : "(NULL)");
2112 |   }
2113 |   
2114 |   return objects_to_be_returned; 
2115 | }
2116 | 
2117 | 
2118 | 
2119 | /* gets one or more person/role objects filters out the ones which don't have the same
2120 |    nic_hdl as 'char * nic_hdl' argument */
2121 | char * up_filter_out_diff_nichdls(char * objects_str, char * nic_hdl)
2122 | {
2123 |   GList * object_str_list = NULL, * object_str_item =NULL;
2124 |   char * objects_to_be_returned = NULL;
2125 |   char * key = NULL;
2126 |   rpsl_object_t *object;
2127 |   
2128 |   if (tracing)
2129 |   {
2130 |     printf("TRACING: up_filter_out_diff_nichdls\n");
2131 |   }
2132 | 
2133 |   /* strip the lines beginning with '%' off */
2134 |   objects_str = strip_lines(objects_str);
2135 |   
2136 |   /* separate the objects strings, store them in a linked list */
2137 |   object_str_list = take_objects(objects_str);
2138 | 
2139 |   for (object_str_item = object_str_list; object_str_item != NULL; object_str_item = g_list_next(object_str_item))
2140 |   {
2141 |     object = rpsl_object_init((char *)(object_str_item->data));
2142 |     key = get_search_key(object, "nic-hdl");
2143 |     if (key != NULL && strcasecmp(g_strstrip(nic_hdl), key) == 0)
2144 | 	{
2145 |       if (objects_to_be_returned == NULL)
2146 | 	  {
2147 |         objects_to_be_returned = strdup((char *)(object_str_item->data));
2148 |       }
2149 | 	  else
2150 | 	  {
2151 |         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
2152 |                       strlen(objects_to_be_returned) + strlen((char *)(object_str_item->data)) + 2);
2153 |         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
2154 |         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_str_item->data));
2155 |       }
2156 |     }
2157 |     rpsl_object_delete(object);
2158 |   }
2159 | 
2160 |   if(tracing)
2161 |   {
2162 |       printf("TRACING: up_filter_out_diff_nichdls: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned :"(NULL)");
2163 |   }
2164 | 
2165 |   return objects_to_be_returned; 
2166 | }
2167 | 
2168 | 
2169 | 
2170 | /* gets one or more route objects, filters out the ones which have the same
2171 |    origin as 'char * origin' argument */
2172 | char * UP_filter_out_same_origins(char * objects_str, rpsl_object_t * object)
2173 | {
2174 |   GList * object_list = NULL, * object_item =NULL;
2175 |   const GList *error_list = NULL; 
2176 |   char * objects_to_be_returned = NULL;
2177 |   char * key = NULL;
2178 |   rpsl_object_t  *obj;
2179 |   char * origin;
2180 |     
2181 |   if (tracing)
2182 |   {
2183 |     printf("TRACING: UP_filter_out_same_origins\n");
2184 |   }
2185 | 
2186 |   origin = get_search_key(object, "origin");
2187 | 
2188 |   /* strip the lines beginning with '%' off */
2189 |   objects_str = strip_lines(objects_str);
2190 |   
2191 |   /* separate the objects, store them in a linked list */
2192 |   object_list = take_objects(objects_str);
2193 | 
2194 |   for (object_item = object_list; object_item != NULL; object_item = g_list_next(object_item))
2195 |   {
2196 |     obj = rpsl_object_init((char *)(object_item->data));
2197 | 	error_list = rpsl_object_errors(obj);
2198 | 
2199 |     key = get_search_key(obj, "origin");
2200 |     if (key != NULL && strcasecmp(g_strstrip(origin), key) != 0)
2201 | 	{
2202 |       if (objects_to_be_returned == NULL)
2203 | 	  {
2204 |         objects_to_be_returned = strdup((char *)(object_item->data));
2205 |       }
2206 | 	  else
2207 | 	  {
2208 |         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
2209 |                       strlen(objects_to_be_returned) + strlen((char *)(object_item->data)) + 2);
2210 |         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
2211 |         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_item->data));
2212 |       }
2213 |     }
2214 | 	rpsl_object_delete(obj);
2215 |   }
2216 | 
2217 |   if (tracing)
2218 |   {
2219 |       printf("TRACING: up_filter_out_same_origins: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned : "(NULL)");
2220 |   }
2221 | 
2222 |   return objects_to_be_returned; 
2223 | }
2224 | 
2225 | 
2226 | 
2227 | /* If the status is ALLOCATED PI or ALLOCATED PA (inetnum) 
2228 |    or ALLOCATED-BY-RIR (inet6num)
2229 |    only valid if the maintainers in the mnt-by attributes contain 
2230 |    at least one of the names mentioned in ALLOCMNT config variable. 
2231 |    Receives an object as a parsed object
2232 |             the type (inetnum or inet6num)
2233 |             the new status value
2234 |    Returns UP_AUTH_OK if the status/mnt-by combination is valid
2235 |            UP_AUF     if the status/mnt-by combination is not valid
2236 | */
2237 | int up_check_reserved_status(rpsl_object_t *object, const char *type, char *new_status)
2238 | {
2239 |   GList * mnt_by_list = NULL;
2240 |   GList *item;
2241 | 
2242 |   char *status;
2243 |   char *mnt_by;
2244 |   char **allocmnt_list;
2245 |   int i;
2246 | 
2247 |   /* Gather a list of mnt-by attributes */
2248 |   mnt_by_list = rpsl_object_get_attr(object, "mnt-by");
2249 |   rpsl_attr_split_multiple(&mnt_by_list);
2250 | 
2251 |   status = strdup(new_status);
2252 |   g_strdown(status);
2253 |  
2254 |   /* construct a list of mntners that are in allocmnt */
2255 |   allocmnt_list = g_strsplit(allocmnt, " ", 0); /* delimited by " " */
2256 |    
2257 |   if ( (! strcmp(type, "inetnum") && strstr(status, "allocated") != NULL)
2258 |       || (! strcmp(type, "inet6num") && strstr(status, "allocated-by-rir") != NULL) )
2259 |   { 
2260 |     free(status);
2261 |     
2262 |     for ( item = mnt_by_list; item != NULL ; item = g_list_next(item) )
2263 | 	{
2264 |       mnt_by = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
2265 |       for (i=0; allocmnt_list[i] != NULL; i++)
2266 | 	  { 
2267 |         /* loop thru the list of allocmnt maintainers */
2268 |         if ((strlen(allocmnt_list[i]) != 0) && strcasecmp(mnt_by, allocmnt_list[i]) == 0)
2269 | 		{
2270 |           /* this mnt-by is in the allocmnt list */
2271 |           free(mnt_by);
2272 |           g_strfreev(allocmnt_list);
2273 |           rpsl_attr_delete_list(mnt_by_list);
2274 |           return UP_AUTH_OK; 
2275 |         }
2276 |       }  
2277 |       free(mnt_by);
2278 |     }
2279 |     
2280 |     g_strfreev(allocmnt_list);
2281 |     rpsl_attr_delete_list(mnt_by_list);
2282 |     
2283 |     /* none of the mnt-by are in the allocmnt list */
2284 |     return UP_AUF;
2285 |   }
2286 |   else
2287 |   {  /* the status attribute is not a reserved category */
2288 |     free(status);
2289 |     g_strfreev(allocmnt_list);
2290 |     rpsl_attr_delete_list(mnt_by_list);
2291 | 
2292 |     return UP_AUTH_OK;
2293 |   }
2294 | }
2295 | 
2296 | 
2297 | 
2298 | 
2299 | /*  Get the value of the status of an inet(6)num object 
2300 |     Receives an object as a parsed object
2301 |     Returns the status value or NULL if none found
2302 | */
2303 | 
2304 | char * up_get_status(rpsl_object_t *object)
2305 | {
2306 |    GList *status_attrs;
2307 |    char *status;
2308 | 
2309 |    status_attrs = rpsl_object_get_attr(object, "status");
2310 |    if ( status_attrs != NULL )
2311 |    {
2312 |      status = rpsl_attr_get_clean_value((rpsl_attr_t *)(status_attrs->data));
2313 |      rpsl_attr_delete_list(status_attrs);
2314 |      return status;
2315 |    }
2316 |    else
2317 |      return NULL;
2318 | }
2319 | 
2320 | 
2321 | 
2322 | /*  Get the value of the status of the more/less specific object for an inet(6)num object 
2323 |     Receives an object as a parsed object
2324 |              the type (inetnum or inet6num)
2325 |              address of the status value pointer
2326 |              flag (-m or -l)
2327 |     Returns NULL   if there is no more/less specific inet(6)num object
2328 |             1 if there is a more/less specific inet(6)num object
2329 |             status value (or NULL if none found) set in the address
2330 | */
2331 | 
2332 | int up_get_specific_status(rpsl_object_t *object, const char *type, char **status, char *flag)
2333 | {
2334 |    const GList *error_list = NULL;
2335 |    char *specific_object_str = NULL;
2336 | 
2337 |    rpsl_object_t *specific_obj = NULL;
2338 | 
2339 |    /* get the one more/less specific inet(6)num object */
2340 |    specific_object_str = get_specific(object, type, flag);
2341 |    if (specific_object_str == NULL)
2342 |    {
2343 |      /* there is no more/less specific inet(6)num object */
2344 |      if (tracing)
2345 |      {
2346 |        printf("TRACING: up_get_specific_status: no %s inet(6)num object found\n", flag);
2347 |      }
2348 |    
2349 |      *status = NULL;
2350 |      return NULL;
2351 |    }
2352 |    
2353 |    /* don't try to parse the object if the -K flag was used */
2354 |    if ( ! strstr(flag, "K") )
2355 |    {
2356 |      specific_obj = rpsl_object_init(specific_object_str);
2357 |      error_list = rpsl_object_errors(specific_obj);
2358 |      free (specific_object_str);
2359 | 
2360 |      /* get the status of the more/less specific object */
2361 |      *status = up_get_status(specific_obj);
2362 |      rpsl_object_delete(specific_obj);
2363 |    }
2364 | 
2365 |    if (tracing)
2366 |    {
2367 |      printf("TRACING: up_get_specific_status: %s specific_status [%s] \n",
2368 |                   flag, *status ? *status : "NONE");
2369 |    }
2370 |    
2371 |    return 1;
2372 | }
2373 | 
2374 | /*  Find if the inet(6)num object has any more specific objects 
2375 |     Receives an object as a parsed object
2376 |              the type (inetnum or inet6num)
2377 |     Returns NULL   if there is no more specific inet(6)num object
2378 |             1 if there is a more specific inet(6)num object
2379 | */
2380 | 
2381 | int up_find_more_specific(rpsl_object_t *object, const char *type)
2382 | {
2383 |    char *more_specific_object_str = NULL;
2384 | 
2385 |    /* get the one more specific inet(6)num object */
2386 |    more_specific_object_str = get_specific(object, type, "-m -K");
2387 |    if (more_specific_object_str == NULL)
2388 |      return NULL;
2389 |    else
2390 |    {
2391 |      /* there is a more specific inet(6)num object */
2392 |      if (tracing)
2393 |      {
2394 |        printf("TRACING: up_get_more_specific_status: more specific inet(6)num object found\n");
2395 |      }
2396 |    
2397 |      return 1;
2398 |    }
2399 | }
2400 | 
2401 | 
2402 | /* check the new status and less specific status according to the defined rules for inetnum
2403 |    Receives an object as a parsed object
2404 |             the new status
2405 |             the less specific status
2406 |             flag for existance of less specific object 
2407 |                 (NULL - does not exist, not NULL - does exist)
2408 |             the override value
2409 |    Returns standard auth return codes:
2410 |            UP_AUTH_OK         if all the status checks are OK
2411 |            UP_HOF or UP_AUF   if any of the status checks fail
2412 | */
2413 | 
2414 | int up_check_inetnum_status_rules(rpsl_object_t *object, char *new_status, char *less_specific_status, int ls_obj_exists, int overriden)
2415 | {
2416 |   int result;
2417 | 
2418 |   if ( ! ls_obj_exists )
2419 |   {
2420 |      /* there is no less specific inetnum object */
2421 |      if (overriden)
2422 |      {
2423 |        /* override the status check when no less specific object found */
2424 |        return UP_AUTH_OK; 
2425 |      }
2426 |      else
2427 |      {
2428 |        return UP_HOF; /* hierarchical authorisation failed */
2429 |      }
2430 |   }
2431 | 
2432 |   if ( ! less_specific_status )
2433 |   {
2434 |     /* the less specific object exists but has no status value */
2435 |     return UP_HOF; /* hierarchical authorisation failed */
2436 |   }
2437 |   
2438 |   /* check if the status/mnt-by combination is valid */
2439 |   result = up_check_reserved_status(object, "inetnum", new_status);
2440 |   if ( result != UP_AUTH_OK)
2441 |     return result;
2442 | 
2443 |   /* now check the relative status values */
2444 |   if ( ! strcmp(new_status, "LIR-PARTITIONED PA") || ! strcmp(new_status, "LIR-PARTITIONED PI") )
2445 |   {
2446 |     if ( 
2447 | 	     ( (! strcmp(new_status, "LIR-PARTITIONED PA")) && strcmp(less_specific_status, "ALLOCATED PA") && strcmp(less_specific_status, "LIR-PARTITIONED PA") && strcmp(less_specific_status, "ALLOCATED UNSPECIFIED") )
2448 | 	   || 
2449 | 	     ( (! strcmp(new_status, "LIR-PARTITIONED PI")) && strcmp(less_specific_status, "ALLOCATED PI") && strcmp(less_specific_status, "LIR-PARTITIONED PI") && strcmp(less_specific_status, "ALLOCATED UNSPECIFIED") ) 
2450 | 	   )
2451 |     {
2452 | 	  return UP_HOF; /* hierarchical authorisation failed */
2453 |     }
2454 |   }
2455 |   
2456 |   /* all check passed */
2457 |   return UP_AUTH_OK;
2458 | }
2459 | 
2460 | 
2461 | /* check the new status and less specific status according to the defined rules for inet6num
2462 |    Receives an object as a parsed object
2463 |             the new status
2464 |             the less specific status
2465 |             flag for existance of less specific object 
2466 |                 (NULL - does not exist, not NULL - does exist)
2467 |             flag for existance of more specific object 
2468 |             the override value
2469 |    Returns standard auth return codes:
2470 |            UP_AUTH_OK         if all the status checks are OK
2471 |            UP_HOF or UP_AUF   if the any of status checks fail
2472 | */
2473 | 
2474 | int up_check_inet6num_status_rules(rpsl_object_t *object, char *new_status, char *less_specific_status, int ls_obj_exists, int ms_obj_exists, int overriden)
2475 | {
2476 |   int result;
2477 | 
2478 |   if (tracing)
2479 |   {
2480 |     printf("TRACING: up_check_inet6num_status_rules:\n");
2481 |     printf("    new_status [%s] less_specific_status [%s]\n", 
2482 |                    new_status, less_specific_status ? less_specific_status : "NONE");
2483 |     printf("    ls_obj_exists [%d] ms_obj_exists [%d] overriden [%d]\n", 
2484 |                    ls_obj_exists, ms_obj_exists, overriden);
2485 |   }
2486 | 
2487 |   if ( ! ls_obj_exists )
2488 |   {
2489 |      /* there is no less specific inet6num object */
2490 |      if (overriden)
2491 |      {
2492 |        /* override the status check when no less specific object found */
2493 |        return UP_AUTH_OK; 
2494 |      }
2495 |      else
2496 |      {
2497 |        return UP_HOF; /* hierarchical authorisation failed */
2498 |      }
2499 |   }
2500 | 
2501 |   if ( ! less_specific_status )
2502 |   {
2503 |     /* the less specific object has no status value */
2504 |     return UP_HOF; /* hierarchical authorisation failed */
2505 |   }
2506 | 
2507 |   if ( strcasecmp(less_specific_status, "ALLOCATED-BY-RIR") 
2508 |     && strcasecmp(less_specific_status, "ALLOCATED-BY-LIR") 
2509 |     && strcasecmp(less_specific_status, "ASSIGNED") )
2510 |   {
2511 |     /* the less specific inet6num status is not recognised */
2512 | 	return UP_HOF; /* hierarchical authorisation failed */
2513 |   }
2514 |   
2515 |   /* check if the status/mnt-by combination is valid */
2516 |   result = up_check_reserved_status(object, "inet6num", new_status);
2517 |   if ( result != UP_AUTH_OK)
2518 |     return result;
2519 | 
2520 |   /* check the relative status rules */
2521 |   if ( ! strcasecmp(new_status, "ASSIGNED") || ! strcasecmp(new_status, "ALLOCATED-BY-LIR") )
2522 |   {
2523 |     /* less specific status must be ALLOCATED-BY-LIR or ALLOCATED-BY-RIR */
2524 |     if ( strcasecmp(less_specific_status, "ALLOCATED-BY-RIR")
2525 |       && strcasecmp(less_specific_status, "ALLOCATED-BY-LIR") )
2526 |     {
2527 |       /* invalid status */
2528 | 	  return UP_HOF; /* hierarchical authorisation failed */
2529 |     }
2530 |   }
2531 | 
2532 |   if ( ! strcasecmp(new_status, "ASSIGNED") && ms_obj_exists )
2533 |   {
2534 |     /* invalid status */
2535 | 	return UP_HOF; /* hierarchical authorisation failed */
2536 |   }
2537 |   
2538 |   return UP_AUTH_OK;
2539 | }
2540 | 
2541 | 
2542 | /*  Check the status value of an inet(6)num object against the hierarchical rules.
2543 |     Receives the new object and old (or NULL if creation) object as parsed objects.
2544 |              the type (inetnum or inet6num)
2545 |              the override value
2546 |     Returns standard auth return codes:
2547 |             UP_AUTH_OK if the status checks are OK
2548 |             UP_HOF     if the status checks fail
2549 | */
2550 | 
2551 | int up_check_status(rpsl_object_t *new_object, rpsl_object_t *old_object, const char *type, int overriden)
2552 | {
2553 |   rpsl_object_t *object;
2554 |   const GList *error_list = NULL;
2555 |   char *old_status = NULL;
2556 |   char *new_status = NULL;
2557 |   char *less_specific_status = NULL;
2558 |   char *more_specific_status = NULL;
2559 |   int result = NULL;
2560 |   int ls_obj_exists = NULL;
2561 |   int ms_obj_exists = NULL;
2562 |   int update = NULL;
2563 | 
2564 |   if (tracing)
2565 |   {
2566 |     printf("TRACING: up_check_status running\n");
2567 |   }
2568 | 
2569 |   if ( new_object != NULL && old_object == NULL )
2570 |   {
2571 |     /* this is a creation */
2572 |     update = NULL;
2573 |     object = new_object;
2574 |   }
2575 |   else if ( new_object != NULL && old_object != NULL )
2576 |   {
2577 |     /* this is an update */
2578 |     update = 1;
2579 |     object = old_object;
2580 |   }
2581 |   else
2582 |   {
2583 |     /* this is a deletion, no status checks required */
2584 |     return UP_AUTH_OK;
2585 |   }
2586 | 
2587 |   /* get the status of the new inetnum object */
2588 |   new_status = up_get_status(new_object);
2589 |   if ( ! new_status )
2590 |   {
2591 |     die;  /* should not happen, syntax error should already have been trapped */
2592 |   }
2593 | 
2594 |   if ( update )
2595 |   {
2596 |     /* get the status of the old inetnum object */
2597 |     old_status = up_get_status(old_object);
2598 |     if ( ! old_status )
2599 |     {
2600 | 	  old_status = strdup("");  /* to allow for legacy objects with no status */
2601 |     }
2602 |   }
2603 | 
2604 |   if (tracing)
2605 |   {
2606 |     printf("TRACING: check_status: old_status [%s] new status [%s]\n",
2607 |                   update ? old_status : "N/A", new_status );
2608 |   }
2609 | 
2610 |   if ( ! update || strcmp(new_status, old_status) )
2611 |   {
2612 |     /* this is a creation or
2613 |        it is an update and the status has changed, 
2614 |        make sure the new value is allowed */
2615 | 
2616 |     /* get the status of the less specific and more specific objects */
2617 |     ls_obj_exists = up_get_specific_status(object, type, &less_specific_status, "-l");
2618 |     if ( ! strcmp(type, "inet6num") )
2619 |       ms_obj_exists = up_get_specific_status(object, type, &more_specific_status, "-m -K");
2620 | 
2621 |     if ( ! strcmp(type, "inetnum") )
2622 |       result = up_check_inetnum_status_rules(object, new_status, less_specific_status, ls_obj_exists, overriden);
2623 |     else
2624 |       result = up_check_inet6num_status_rules(object, new_status, less_specific_status, ls_obj_exists, ms_obj_exists, overriden);
2625 | 
2626 |     if ( less_specific_status )
2627 |       free(less_specific_status);
2628 |     if ( old_status )
2629 | 	  free (old_status);
2630 |     free (new_status);
2631 | 
2632 |     return result;
2633 |   }
2634 |   else
2635 |   {
2636 |     /* update with no change in status, so no checks required */
2637 |     return UP_AUTH_OK;
2638 |   }
2639 | }
2640 | 
2641 | 
2642 | /* Check authorisation
2643 |    Applies authorisation rules according to the object type 
2644 |    
2645 |    Arguments:
2646 |       char *new_object: the new object,
2647 |       char *old_object: the old object, as found in the database,
2648 |       char *type: type of the object
2649 |       credentials_struct credentials: a struct which
2650 |         contains credentials of the update, such as 'From:' field of
2651 |         the e-mail header and passwords in the update   */
2652 | 
2653 | int check_auth(rpsl_object_t *new_object, rpsl_object_t *old_object, const char *type, credentials_struct credentials)
2654 | {
2655 |    GList *old_mntners = NULL, *new_mntners = NULL;
2656 |    GList *old_irts = NULL, *new_irts = NULL;
2657 |    GList *changed_irts = NULL; 
2658 |    GList *as_block_mnt_lowers = NULL;
2659 |    GSList *old_auth_vector = NULL, *new_auth_vector = NULL;
2660 |    GSList *changed_auth_vector = NULL;
2661 |    GSList *as_block_auth_vector = NULL;
2662 |    GSList *less_specific_auth_vector = NULL;
2663 |    GList *less_specific_mnt_lowers = NULL;
2664 |    GList *less_specific_mntners = NULL;
2665 |    GList *aut_num_maintainers = NULL;
2666 |    GSList *aut_num_auth_vector = NULL;
2667 |    GList *exact_match_routes_str = NULL;  
2668 |    GList *exact_match_routes_maintainers = NULL;
2669 |    GSList *exact_match_routes_auth_vector = NULL;
2670 |    GList *exact_match_maintainers = NULL;
2671 |    GSList *exact_match_auth_vector = NULL;
2672 |    GList *less_spec_routes_str = NULL;
2673 |    GList *less_spec_routes_mntners = NULL;
2674 |    GSList *less_spec_routes_auth_vector = NULL;
2675 |    GList *exact_match_inetnum_mnt_routes = NULL;
2676 |    GSList *exact_match_inetnum_auth_vector = NULL;
2677 |    GList *less_spec_inetnum_mntners = NULL;
2678 |    GSList *less_spec_inetnum_auth_vector = NULL;
2679 |    GList *less_spec_inetnum_mnt_bys = NULL;
2680 |    GList *exact_match_inetnum_mnt_bys;
2681 | 
2682 |    GList *old_name = NULL;
2683 |    GList *new_name = NULL;
2684 |    GList *attr;
2685 |    const GList *error_list = NULL;
2686 |    GList *status_attrs;
2687 | 
2688 |    char *less_specific_status;
2689 |    char *old_status;
2690 |    char *new_status;
2691 |    int status_result;
2692 |    char *as_block_object_str = NULL;
2693 |    char *less_specific_object_str = NULL;
2694 |    char *less_specific_domain_str = NULL;
2695 |    char *less_spec_inetnum_str = NULL;
2696 |    char *exact_match_inetnum_str = NULL;
2697 |    const char *less_specific_object_type = NULL;
2698 |    char *override_string = NULL;
2699 |    char *set_name = NULL;
2700 |    char * aut_num_object_str = NULL;
2701 |    char * name_old = NULL;
2702 |    char * name_new = NULL;
2703 |    const char *name;
2704 |    int aut_num_auth_OK = FALSE;
2705 | 
2706 |    int auth_return, saved_auth_return;
2707 |    char *value;
2708 | 
2709 |    rpsl_object_t *as_block_obj = NULL;
2710 |    rpsl_object_t *less_specific_obj = NULL;
2711 |    rpsl_object_t *less_specific_domain_obj = NULL;
2712 |    rpsl_object_t *aut_num_obj = NULL;
2713 |    rpsl_object_t *exact_match_inetnum_obj = NULL;
2714 |    rpsl_object_t *less_spec_inetnum_obj = NULL;
2715 | 
2716 |    int overriden = 0;
2717 |    
2718 |    if (tracing)
2719 |    {                                
2720 | 	 printf("TRACING: check_auth is running with object type [%s]\n", type);
2721 |    }
2722 | 
2723 |    /* first check if it is overriden or not. if overriden, check the override
2724 |       password. If it is correct, continue, setting "overriden" to 1. If not,   
2725 |       immediately exit returning ERR_UP_OVF                                   */
2726 |    override_string = get_override((new_object == NULL) ? old_object : new_object );
2727 |    if(override_string == NULL)
2728 |    { 
2729 | 	 if (tracing)
2730 | 	 {                                
2731 | 	   printf("TRACING: overriden not set\n");
2732 | 	 }
2733 |      overriden = 0;
2734 |    }
2735 |    else if ( check_override(override_string) == OVR_OK )
2736 |    {
2737 | 	 if (tracing)
2738 | 	 {                                
2739 | 	   printf("TRACING: overriden set\n");
2740 | 	 }
2741 |      overriden = 1; /* authorisation is overriden */
2742 |      free(override_string);
2743 | 	 override_string = NULL;
2744 |    }
2745 |    else
2746 |    {
2747 | 	 if (tracing)
2748 | 	 {                                
2749 | 	   printf("TRACING: override failed\n");
2750 | 	 }
2751 |      free(override_string);
2752 | 	 override_string = NULL;
2753 |      return UP_OVF; /* override failed! */
2754 |    }
2755 | 
2756 | 
2757 |    /*  
2758 |     *  Handle the "person", "role", "limerick", "inet-rtr", "key-cert" types 
2759 |     */
2760 |    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
2761 |       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ||
2762 |       strcmp(type,"key-cert") == 0 )
2763 |    {
2764 |      if( new_object == NULL && old_object != NULL )
2765 | 	 { /* the object is to be deleted */
2766 |        old_mntners = get_mntners(old_object);
2767 |        old_auth_vector = get_auth_vector(old_mntners);
2768 |        if (old_mntners != NULL && old_auth_vector == NULL)
2769 | 	   {
2770 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2771 | 		 rpsl_attr_delete_list(old_mntners);
2772 |          return UP_AUF; /* auth failed */
2773 |        }
2774 |        auth_return = authorise(old_auth_vector, credentials, overriden);
2775 |        if (old_auth_vector)
2776 | 	     g_slist_free(old_auth_vector);
2777 | 	   return auth_return;
2778 |      }
2779 | 	 else if ( new_object != NULL && old_object == NULL )
2780 | 	 { /* the object is to be created */
2781 |        new_mntners = get_mntners(new_object);
2782 |        new_auth_vector = get_auth_vector(new_mntners);
2783 |        if(new_mntners != NULL && new_auth_vector == NULL)
2784 | 	   {
2785 |          /* then, the mntners in 'new_mntners' do not exist. Problem. */
2786 | 		 rpsl_attr_delete_list(new_mntners);
2787 |          return UP_AUF; /* auth failed */
2788 |        }
2789 |        auth_return = authorise(new_auth_vector, credentials, overriden);
2790 | 	   if (new_auth_vector)
2791 | 	     g_slist_free(new_auth_vector);
2792 | 	   return auth_return;
2793 |      }
2794 | 	 else if ( new_object != NULL && old_object != NULL )
2795 | 	 { /* this is an update */
2796 |        /* check name change of person/role */
2797 |        if ( strcmp(type,"person") == 0 || strcmp(type,"role") == 0 )
2798 | 	   {
2799 |          old_name = get_attr_list(old_object, type);
2800 |          new_name = get_attr_list(new_object, type);
2801 | 
2802 |          if(old_name != NULL && new_name != NULL
2803 |              && g_list_nth(old_name, 0) != NULL && g_list_nth(new_name, 0) != NULL
2804 |              && (g_list_nth(old_name, 0)->data) != NULL
2805 |              && (g_list_nth(new_name, 0)->data) != NULL)
2806 |          {
2807 | 
2808 |            name_old = rpsl_attr_get_clean_value((rpsl_attr_t *)(g_list_nth(old_name, 0)->data));
2809 |            name_new = rpsl_attr_get_clean_value((rpsl_attr_t *)(g_list_nth(new_name, 0)->data));
2810 | 		   rpsl_attr_delete_list(old_name);
2811 | 		   rpsl_attr_delete_list(new_name);
2812 | 
2813 |            if ( strcmp(name_old, name_new) )
2814 | 		   {
2815 |              free(name_old); free(name_new);
2816 |              return UP_NAM; /* name of a person/role object can't be changed */
2817 |            }
2818 |            free(name_old);free(name_new);
2819 |          }
2820 | 		 else
2821 | 		 {
2822 | 		   rpsl_attr_delete_list(old_name);
2823 | 		   rpsl_attr_delete_list(new_name);
2824 |            return UP_INT; /* there was a problem with obtaining the name of person obj */
2825 |          }
2826 |        }
2827 |       
2828 |        old_mntners = get_mntners(old_object);
2829 |        old_auth_vector = get_auth_vector(old_mntners);
2830 |        if (old_mntners != NULL && old_auth_vector == NULL)
2831 | 	   {
2832 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2833 | 		 rpsl_attr_delete_list(old_mntners);
2834 |          return UP_AUF; /* auth failed */
2835 |        }
2836 |        if (old_auth_vector)
2837 | 	   { /* if we have mntners in the old object, use them */
2838 |          auth_return = authorise(old_auth_vector, credentials, overriden);
2839 | 	     g_slist_free(old_auth_vector);
2840 | 	     return auth_return;
2841 |        }
2842 | 	   else
2843 | 	   {
2844 |          new_mntners = get_mntners(new_object);
2845 |          new_auth_vector = get_auth_vector(new_mntners);
2846 |          if (new_mntners != NULL && new_auth_vector == NULL)
2847 | 		 {
2848 |            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2849 | 		   rpsl_attr_delete_list(new_mntners);
2850 |            return UP_AUF; /* auth failed */
2851 |          }
2852 |          auth_return = authorise(new_auth_vector, credentials, overriden);
2853 | 		 if (new_auth_vector)
2854 | 	       g_slist_free(new_auth_vector);
2855 | 	     return auth_return;
2856 |        }
2857 |      }
2858 | 	 else
2859 | 	 { /* both are NULL, mustn't happen */
2860 |          if (tracing)
2861 | 		 {
2862 |            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
2863 |          }
2864 |          return UP_INT; /* internal error */
2865 |      }
2866 |    }
2867 | 
2868 |    /*  
2869 |     *  Handle the "aut-num" type 
2870 |     */
2871 |    else if (strcmp(type,"aut-num")  == 0 )
2872 |    {
2873 |      if ( new_object == NULL && old_object != NULL )
2874 | 	 { /* the object is to be deleted */
2875 |        old_mntners = get_mntners(old_object);
2876 |        old_auth_vector = get_auth_vector(old_mntners);
2877 |        if (old_mntners != NULL && old_auth_vector == NULL)
2878 | 	   {
2879 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2880 | 		 rpsl_attr_delete_list(old_mntners);
2881 |          return UP_AUF; /* auth failed */
2882 |        }
2883 |        auth_return = authorise(old_auth_vector, credentials, overriden);
2884 | 	   g_slist_free(old_auth_vector);
2885 | 	   return auth_return;
2886 |      }
2887 | 	 else if ( new_object != NULL && old_object == NULL )
2888 | 	 { /* the object is to be created */
2889 |        as_block_object_str = get_as_block(new_object);
2890 |        if (as_block_object_str == NULL )
2891 | 	   {
2892 |          return UP_ABN; /* As-block does not exist */
2893 |        } 
2894 | 	   else
2895 | 	   {
2896 | 	     as_block_obj = rpsl_object_init(as_block_object_str);
2897 | 		 if (tracing)
2898 | 		 {
2899 |     	   if ( rpsl_object_has_error(as_block_obj, RPSL_ERRLVL_ERROR) )
2900 | 		   {
2901 | 			 /* thre was an error during the parsing */
2902 | 			 name = rpsl_object_get_class(as_block_obj);
2903 | 			 if ( name )
2904 | 			 {
2905 | 			   attr = rpsl_object_get_attr(as_block_obj, name);
2906 | 			   if ( attr )
2907 | 			   {
2908 | 		    	 value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
2909 | 				 if ( value )
2910 | 				 {
2911 | 		    	   printf("TRACING: get_mnt_routes_from_list: error parsing as_block object %s\n", value );
2912 | 				   free(value);
2913 | 				 }
2914 | 				 else
2915 | 		    	   printf("TRACING: get_mnt_routes_from_list: error parsing as_block object\n");
2916 | 
2917 | 				 rpsl_attr_delete_list(attr);
2918 | 			   }
2919 | 			 }
2920 | 		   }
2921 | 		 }
2922 | 
2923 |          as_block_mnt_lowers = get_mnt_lowers(as_block_obj);
2924 |          as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
2925 | 		 rpsl_object_delete(as_block_obj);
2926 |          if (as_block_mnt_lowers != NULL && as_block_auth_vector == NULL)
2927 | 		 {
2928 |            /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
2929 | 		   rpsl_attr_delete_list(as_block_mnt_lowers);
2930 |            return UP_AUF; /* auth failed */
2931 |          }
2932 |          auth_return = authorise(as_block_auth_vector, credentials, overriden);
2933 |          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
2934 | 		 {
2935 |            saved_auth_return = auth_return;
2936 |            new_mntners = get_mntners(new_object);
2937 |            new_auth_vector = get_auth_vector(new_mntners);
2938 |            if(new_mntners != NULL && new_auth_vector == NULL)
2939 | 		   {
2940 |              /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2941 | 		     rpsl_attr_delete_list(new_mntners);
2942 |              return UP_AUF; /* auth failed */
2943 |            }
2944 |            auth_return = authorise(new_auth_vector, credentials, overriden);
2945 | 		   if (new_auth_vector)
2946 | 	         g_slist_free(new_auth_vector);
2947 |            if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
2948 |              return UP_OKM;
2949 |            else
2950 |              return auth_return;
2951 |          }
2952 | 		 else
2953 | 		 {
2954 |            return UP_HOF; /* hierarchical auth failed */
2955 |          }
2956 |        }
2957 |      }
2958 | 	 else if( new_object != NULL && old_object != NULL )
2959 | 	 { /* this is an update */
2960 |        old_mntners = get_mntners(old_object);
2961 |        old_auth_vector = get_auth_vector(old_mntners);
2962 |        if (old_mntners != NULL && old_auth_vector == NULL)
2963 | 	   {
2964 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2965 | 		 rpsl_attr_delete_list(old_mntners);
2966 |          return UP_AUF; /* auth failed */
2967 |        }
2968 |        if (old_auth_vector)
2969 | 	   { /* if we have mntners in the old object, use them */
2970 |          auth_return = authorise(old_auth_vector, credentials, overriden);
2971 | 	     g_slist_free(old_auth_vector);
2972 | 	     return auth_return;
2973 |        }
2974 | 	   else
2975 | 	   {
2976 |          new_mntners = get_mntners(new_object);
2977 |          new_auth_vector = get_auth_vector(new_mntners);
2978 |          if (new_mntners != NULL && new_auth_vector == NULL)
2979 | 		 {
2980 |            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2981 | 		   rpsl_attr_delete_list(new_mntners);
2982 |            return UP_AUF; /* auth failed */
2983 |          }
2984 |          auth_return = authorise(new_auth_vector, credentials, overriden);
2985 | 		 if (new_auth_vector)
2986 |            g_slist_free(new_auth_vector);
2987 | 	     return auth_return;
2988 |        }
2989 |      }
2990 | 	 else
2991 | 	 { /* both are NULL, mustn't happen */
2992 |          if(tracing) 
2993 | 		 {
2994 |            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
2995 |          } 
2996 |          return UP_INT; /* internal error */
2997 |      }
2998 |    } 
2999 | 
3000 |    /*  
3001 |     *  Handle the "mntner/as-block/irt" types 
3002 |     */
3003 |    else if (strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 || strcmp(type,"irt")  == 0 )
3004 |    {
3005 |      if ( new_object == NULL && old_object != NULL )
3006 | 	 { /* the object is to be deleted */
3007 |        old_mntners = get_mntners(old_object);
3008 |        old_auth_vector = get_auth_vector(old_mntners);
3009 |        if (old_mntners != NULL && old_auth_vector == NULL)
3010 | 	   {
3011 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3012 | 		 rpsl_attr_delete_list(old_mntners);
3013 |          return UP_AUF; /* auth failed */
3014 |        }
3015 |        auth_return = authorise(old_auth_vector, credentials, overriden);
3016 | 	   g_slist_free(old_auth_vector);
3017 | 	   return auth_return;
3018 |      }
3019 | 	 else if ( new_object != NULL && old_object == NULL )
3020 | 	 { /* the object is to be created */
3021 |        if (overriden || test_mode)
3022 | 	   {
3023 |          return UP_AUTH_OK; 
3024 |        }
3025 | 	   else
3026 | 	   { /* If not overriden, must be forwarded to <HUMAILBOX> */
3027 |          if (tracing) 
3028 | 		 {
3029 |            printf("TRACING: check_auth: '%s' creation requested\n", type);
3030 |          }
3031 |          return UP_FWD; /* must be forwarded to <HUMAILBOX> */
3032 |        }
3033 |      }
3034 | 	 else if ( new_object != NULL && old_object != NULL )
3035 | 	 { /* this is an update */
3036 |        old_mntners = get_mntners(old_object);
3037 |        old_auth_vector = get_auth_vector(old_mntners);
3038 |        if (old_mntners != NULL && old_auth_vector == NULL)
3039 | 	   {
3040 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3041 | 		 rpsl_attr_delete_list(old_mntners);
3042 |          return UP_AUF; /* auth failed */
3043 |        }
3044 |        if (old_auth_vector)
3045 | 	   { /* if we have mntners in the old object, use them */
3046 |          auth_return = authorise(old_auth_vector, credentials, overriden);
3047 | 	     g_slist_free(old_auth_vector);
3048 | 	     return auth_return;
3049 |        }
3050 | 	   else
3051 | 	   {
3052 |          new_mntners = get_mntners(new_object);
3053 |          new_auth_vector = get_auth_vector(new_mntners);
3054 |          if (new_mntners != NULL && new_auth_vector == NULL)
3055 | 		 {
3056 |            /* then, the mntners in 'new_mntners' do not exist. Problem. */
3057 | 		   rpsl_attr_delete_list(new_mntners);
3058 |            return UP_AUF; /* auth failed */
3059 |          }
3060 |          auth_return = authorise(new_auth_vector, credentials, overriden);
3061 | 		 if (new_auth_vector)
3062 |   	       g_slist_free(new_auth_vector);
3063 | 	     return auth_return;
3064 |        }
3065 |      }
3066 | 	 else
3067 | 	 { /* both are NULL, mustn't happen */
3068 |          if (tracing)
3069 | 		 {
3070 |            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3071 |          }
3072 |          return UP_INT; /* internal error */
3073 |      }
3074 |    }
3075 | 
3076 |    /*  
3077 |     *  Handle the "inetnum/inet6num" types 
3078 |     */
3079 |    else if (strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 )
3080 |    {
3081 |      if ( new_object == NULL && old_object != NULL )
3082 | 	 { 
3083 |        /* the object is to be deleted */
3084 |        /* dont check for mnt-irt on deletion */
3085 | 
3086 |        /******* status check **********/
3087 |        status_result = up_check_status(new_object, old_object, type, overriden);
3088 |        if ( status_result != UP_AUTH_OK )
3089 |          return status_result;
3090 |        
3091 |        /******* mntner check **********/
3092 |        old_mntners = get_mntners(old_object);
3093 |        old_auth_vector = get_auth_vector(old_mntners);
3094 |        if (old_mntners != NULL && old_auth_vector == NULL)
3095 | 	   {
3096 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3097 | 		 rpsl_attr_delete_list(old_mntners);
3098 |          return UP_AUF; /* auth failed */
3099 |        }
3100 |        auth_return = authorise(old_auth_vector, credentials, overriden);
3101 | 	   g_slist_free(old_auth_vector);
3102 | 	   return auth_return;
3103 |      }
3104 | 	 else if ( new_object != NULL && old_object == NULL )
3105 | 	 { 
3106 |        /* the object is to be created */
3107 |        /******* irt check **********/
3108 | 	   /* if an object is created with an mnt-irt attribute, then it must 
3109 |           pass the authorisation for the mnt-irt */
3110 |        new_irts = get_irts(new_object);
3111 |        new_auth_vector = get_irt_auth_vector(new_irts);
3112 |        if (new_irts != NULL && new_auth_vector == NULL)
3113 | 	   {
3114 |          /* then, the irts in 'new_irts' do not exist. Problem. */
3115 | 		 rpsl_attr_delete_list(new_irts);
3116 |          return UP_AUF; /* auth failed */
3117 |        }
3118 |        auth_return = authorise(new_auth_vector, credentials, overriden);
3119 | 	   if (new_auth_vector)
3120 |   	     g_slist_free(new_auth_vector);
3121 |        rpsl_attr_delete_list(new_irts);
3122 | 	   if ( auth_return == UP_AUF || auth_return == UP_MFF || auth_return == UP_MIX )
3123 | 	   {
3124 | 	     return UP_HOF; /* hierarchical authorisation failed */
3125 | 	   }
3126 | 
3127 |        /* get the one less specific inet(6)num object */
3128 |        less_specific_object_str = get_specific(new_object, type, "-l");
3129 |        if (less_specific_object_str == NULL)
3130 | 	   {
3131 |          /* there is no less specific object, fail if not overriden */
3132 |          if ( ! overriden )
3133 | 		 {
3134 |            return UP_HOF; /* hierarchical authorisation failed */
3135 |          }
3136 |        }
3137 | 	   else
3138 | 	   { /* we got a less specific inet(6)num object */
3139 | 	     less_specific_obj = rpsl_object_init(less_specific_object_str);
3140 | 	     error_list = rpsl_object_errors(less_specific_obj);
3141 | 		 if (tracing)
3142 | 		 {
3143 |     	   if ( rpsl_object_has_error(less_specific_obj, RPSL_ERRLVL_ERROR) )
3144 | 		   {
3145 | 			 /* thre was an error during the parsing */
3146 | 			 name = rpsl_object_get_class(less_specific_obj);
3147 | 			 if ( name )
3148 | 			 {
3149 | 			   attr = rpsl_object_get_attr(less_specific_obj, name);
3150 | 			   if ( attr )
3151 | 			   {
3152 | 		    	 value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3153 | 				 if ( value )
3154 | 				 {
3155 | 		    	   printf("TRACING: check_auth: error parsing object %s\n", value );
3156 | 				   free(value);
3157 | 				 }
3158 | 				 else
3159 | 		    	   printf("TRACING: check_auth: error parsing object\n");
3160 | 
3161 | 				 rpsl_attr_delete_list(attr);
3162 | 			   }
3163 | 			 }
3164 | 		   }
3165 | 		 }
3166 | 
3167 |          /******* status check **********/
3168 |          status_result = up_check_status(new_object, old_object, type, overriden);
3169 |          if ( status_result != UP_AUTH_OK )
3170 |          {
3171 | 		   rpsl_object_delete(less_specific_obj);
3172 |            return status_result;
3173 |          }
3174 | 
3175 |          /******* less_specific check **********/
3176 |          less_specific_mnt_lowers = get_mnt_lowers(less_specific_obj);
3177 |          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
3178 | 		 rpsl_object_delete(less_specific_obj);
3179 | 
3180 |          if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
3181 | 		 {
3182 |            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
3183 | 		   rpsl_attr_delete_list(less_specific_mnt_lowers);
3184 |            return UP_AUF; /* auth failed */
3185 |          }
3186 |          auth_return = authorise(less_specific_auth_vector, credentials, overriden);
3187 |          if (less_specific_auth_vector != NULL)
3188 |          {
3189 | 		   g_slist_free(less_specific_auth_vector);
3190 |          }
3191 |          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3192 | 		 {
3193 |            /******* mntner check **********/
3194 |            new_mntners = get_mntners(new_object);
3195 |            new_auth_vector = get_auth_vector(new_mntners);
3196 |            if (new_mntners != NULL && new_auth_vector == NULL)
3197 | 		   {
3198 |              /* then, the mntners in 'new_mntners' do not exist. Problem. */
3199 | 		     rpsl_attr_delete_list(new_mntners);
3200 |              return UP_AUF; /* auth failed */
3201 |            }
3202 |            auth_return = authorise(new_auth_vector, credentials, overriden);
3203 | 		   if (new_auth_vector)
3204 |   	         g_slist_free(new_auth_vector);
3205 | 	       return auth_return;
3206 |          }
3207 | 		 else
3208 | 		 {
3209 |            return UP_HOF; /* hierarchical authorisation failed */
3210 |          }
3211 |        }
3212 |      }
3213 | 	 else if ( new_object != NULL && old_object != NULL )
3214 | 	 { 
3215 |        /* this is an update */
3216 |        /******* status check **********/
3217 |        status_result = up_check_status(new_object, old_object, type, overriden);
3218 |        if ( status_result != UP_AUTH_OK )
3219 |          return status_result;
3220 | 
3221 |        /******* irt check **********/
3222 | 	   /* check for mnt-irt in both old and new object */
3223 |        /* it only needs to pass the authorisation of an mnt-irt when the
3224 |           mnt-irt is first added to the object */
3225 |        old_irts = get_irts(old_object);
3226 |        new_irts = get_irts(new_object);
3227 |        /* find irts that have just been added to this object */
3228 |        changed_irts = NT_compare_lists(old_irts, new_irts, 2);  /* 2 means 'just added' */
3229 |        
3230 |        changed_auth_vector = get_irt_auth_vector(changed_irts);
3231 |        if (changed_irts != NULL && changed_auth_vector == NULL)
3232 | 	   {
3233 |          /* then, the irts in 'changed_irts' do not exist. Problem. */
3234 |          rpsl_attr_delete_list(old_irts);
3235 |          rpsl_attr_delete_list(new_irts);
3236 |          return UP_AUF; /* auth failed */
3237 |        }
3238 |        auth_return = authorise(changed_auth_vector, credentials, overriden);
3239 | 	   g_slist_free(changed_auth_vector);
3240 |        rpsl_attr_delete_list(old_irts);
3241 |        rpsl_attr_delete_list(new_irts);
3242 | 	   if ( auth_return == UP_AUF || auth_return == UP_MFF || auth_return == UP_MIX)
3243 | 	   {
3244 | 	     return UP_HOF; /* hierarchical authorisation failed */
3245 | 	   }
3246 | 
3247 |        /******* mntner check **********/
3248 |        old_mntners = get_mntners(old_object);
3249 |        old_auth_vector = get_auth_vector(old_mntners);
3250 |        if (old_mntners != NULL && old_auth_vector == NULL)
3251 | 	   {
3252 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3253 | 		 rpsl_attr_delete_list(old_mntners);
3254 |          return UP_AUF; /* auth failed */
3255 |        }
3256 |        if (old_auth_vector)
3257 | 	   { /* if we have mntners in the old object, use them */
3258 |          auth_return = authorise(old_auth_vector, credentials, overriden);
3259 | 	     g_slist_free(old_auth_vector);
3260 | 	     return auth_return;
3261 |        }
3262 | 	   else
3263 | 	   {
3264 |          new_mntners = get_mntners(new_object);
3265 |          new_auth_vector = get_auth_vector(new_mntners);
3266 |          if (new_mntners != NULL && new_auth_vector == NULL)
3267 | 		 {
3268 |            /* then, the mntners in 'new_mntners' do not exist. Problem. */
3269 | 		   rpsl_attr_delete_list(new_mntners);
3270 |            return UP_AUF; /* auth failed */
3271 |          }
3272 |          auth_return = authorise(new_auth_vector, credentials, overriden);
3273 | 		 if (new_auth_vector)
3274 |   	       g_slist_free(new_auth_vector);
3275 | 	     return auth_return;
3276 |        }
3277 |      }
3278 | 	 else
3279 | 	 { /* both are NULL, mustn't happen */
3280 |          if (tracing)
3281 | 		 {
3282 |            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3283 |          }
3284 |          return UP_INT; /* internal error */
3285 |      }
3286 |    }
3287 |    
3288 |    /*  
3289 |     *  Handle the "domain" type 
3290 |     */
3291 |    else if (strcmp(type,"domain")  == 0)
3292 |    {
3293 |      if ( new_object == NULL && old_object != NULL )
3294 | 	 { /* the object is to be deleted */
3295 |        old_mntners = get_mntners(old_object);
3296 |        old_auth_vector = get_auth_vector(old_mntners);
3297 |        if (old_mntners != NULL && old_auth_vector == NULL)
3298 | 	   {
3299 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3300 | 		 rpsl_attr_delete_list(old_mntners);
3301 |          return UP_AUF; /* auth failed */
3302 |        }
3303 |        auth_return = authorise(old_auth_vector, credentials, overriden);
3304 | 	   g_slist_free(old_auth_vector);
3305 | 	   return auth_return;
3306 |      }
3307 | 	 else if ( new_object != NULL && old_object == NULL )
3308 | 	 { /* the object is to be created */
3309 |        /* now, we have to find a 'less specific domain object' for this. 
3310 |           If there is no less specific object, then creation is possible
3311 |           only with overriding. */
3312 |       less_specific_domain_str = get_less_specific_domain(new_object);
3313 |       if (less_specific_domain_str == NULL)
3314 | 	  {
3315 |         if (overriden)
3316 | 		{/* we didn't get a 'less specific' domain object */
3317 |            return UP_AUTH_OK; 
3318 |          }
3319 | 		 else
3320 | 		 {
3321 |            return UP_HOF; /* hierarchical authorisation failed */
3322 |          }
3323 |       }
3324 | 	  else
3325 | 	  { /* we get a 'less specific' domain object */
3326 | 	     less_specific_domain_obj = rpsl_object_init(less_specific_domain_str);
3327 | 		 if (tracing)
3328 | 		 {
3329 |     	   if ( rpsl_object_has_error(less_specific_domain_obj, RPSL_ERRLVL_ERROR) )
3330 | 		   {
3331 | 			 /* thre was an error during the parsing */
3332 | 			 name = rpsl_object_get_class(less_specific_domain_obj);
3333 | 			 if ( name )
3334 | 			 {
3335 | 			   attr = rpsl_object_get_attr(less_specific_domain_obj, name);
3336 | 			   if ( attr )
3337 | 			   {
3338 | 		    	 value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3339 | 				 if ( value )
3340 | 				 {
3341 | 		    	   printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3342 | 				   free(value);
3343 | 				 }
3344 | 				 else
3345 | 		    	   printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3346 | 
3347 | 				 rpsl_attr_delete_list(attr);
3348 | 			   }
3349 | 			 }
3350 | 		   }
3351 | 		 }
3352 | 
3353 |          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain_obj);
3354 |          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
3355 |          rpsl_object_delete(less_specific_domain_obj);
3356 | 
3357 |          if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
3358 | 		 {
3359 |            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
3360 | 		   rpsl_attr_delete_list(less_specific_mnt_lowers);
3361 |            return UP_AUF; /* auth failed */
3362 |          }
3363 |          auth_return = authorise(less_specific_auth_vector, credentials, overriden);
3364 |          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3365 | 		 {
3366 |            saved_auth_return = auth_return;
3367 |            new_mntners = get_mntners(new_object);
3368 |            new_auth_vector = get_auth_vector(new_mntners);
3369 |            if (new_mntners != NULL && new_auth_vector == NULL)
3370 | 		   {
3371 |              /* then, the mntners in 'new_mntners' do not exist. Problem. */
3372 | 		     rpsl_attr_delete_list(new_mntners);
3373 |              return UP_AUF; /* auth failed */
3374 |            }
3375 |            auth_return = authorise(new_auth_vector, credentials, overriden);
3376 | 		   if (new_auth_vector)
3377 |   	         g_slist_free(new_auth_vector);
3378 |            if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM )
3379 |              return UP_OKM;
3380 |            else
3381 | 	         return auth_return;
3382 |          }
3383 | 		 else
3384 | 		 {
3385 |            return UP_HOF; /* hierarchical authorisation failed */
3386 |          }
3387 |       }
3388 |      }
3389 | 	 else if ( new_object != NULL && old_object != NULL )
3390 | 	 { /* this is an update */
3391 |        old_mntners = get_mntners(old_object);
3392 |        old_auth_vector = get_auth_vector(old_mntners);
3393 |        if (old_mntners != NULL && old_auth_vector == NULL)
3394 | 	   {
3395 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3396 | 		 rpsl_attr_delete_list(old_mntners);
3397 |          return UP_AUF; /* auth failed */
3398 |        }
3399 |        if (old_auth_vector)
3400 | 	   { /* if we have mntners in the old object, use them */
3401 |          auth_return = authorise(old_auth_vector, credentials, overriden);
3402 | 	     g_slist_free(old_auth_vector);
3403 | 	     return auth_return;
3404 |        }
3405 | 	   else
3406 | 	   {
3407 |          new_mntners = get_mntners(new_object);
3408 |          new_auth_vector = get_auth_vector(new_mntners);
3409 |          if (new_mntners != NULL && new_auth_vector == NULL)
3410 | 		 {
3411 |            /* then, the mntners in 'new_mntners' do not exist. Problem. */
3412 | 		   rpsl_attr_delete_list(new_mntners);
3413 |            return UP_AUF; /* auth failed */
3414 |          }
3415 |          auth_return = authorise(new_auth_vector, credentials, overriden);
3416 | 		 if (new_auth_vector)
3417 |   	       g_slist_free(new_auth_vector);
3418 | 	     return auth_return;
3419 |        }
3420 |      }
3421 | 	 else
3422 | 	 { /* both are NULL, mustn't happen */
3423 |          if (tracing)
3424 | 		 {
3425 |            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3426 |          }
3427 |          return UP_INT; /* internal error */
3428 |      }
3429 |    }
3430 |    
3431 | 
3432 |    /*  
3433 |     *  Handle the "route" type 
3434 |     */
3435 |    else if (strcmp(type,"route")  == 0)
3436 |    {
3437 |      if ( new_object == NULL && old_object != NULL )
3438 | 	 { /* the object is to be deleted */
3439 |        old_mntners = get_mntners(old_object);
3440 |        old_auth_vector = get_auth_vector(old_mntners);
3441 |        if (old_mntners != NULL && old_auth_vector == NULL)
3442 | 	   {
3443 |          /* then, the mntners in 'old_mntners' do not exist. Problem. */
3444 | 		 rpsl_attr_delete_list(old_mntners);
3445 |          return UP_AUF; /* auth failed */
3446 |        }
3447 |        auth_return = authorise(old_auth_vector, credentials, overriden);
3448 | 	   g_slist_free(old_auth_vector);
3449 | 	   return auth_return;
3450 |      } 
3451 | 	 else if ( new_object != NULL && old_object == NULL )
3452 | 	 { /* the object is to be created */
3453 |        /* first we have to find the aut-num object mentioned in the 
3454 |           origin attribute */
3455 | 
3456 |        aut_num_object_str = get_aut_num_object(new_object); 
3457 |        if (aut_num_object_str == NULL)
3458 | 	   {
3459 |          if (overriden)
3460 | 		 {
3461 |            return UP_AUTH_OK; 
3462 |          }
3463 | 		 else
3464 | 		 {
3465 |            return UP_HOF; /* hierarchical authorisation failed */
3466 |          }
3467 |        }
3468 | 	   else
3469 | 	   { /* there is a corresponding aut-num in the db */
3470 |          if (tracing)
3471 | 		 {
3472 |            printf("TRACING: check_auth: will try to authorise the route using aut-num\n");
3473 |          }
3474 | 	     aut_num_obj = rpsl_object_init(aut_num_object_str);
3475 | 		 if (tracing)
3476 | 		 {
3477 |     	   if ( rpsl_object_has_error(aut_num_obj, RPSL_ERRLVL_ERROR) )
3478 | 		   {
3479 | 			 /* thre was an error during the parsing */
3480 | 			 name = rpsl_object_get_class(aut_num_obj);
3481 | 			 if ( name )
3482 | 			 {
3483 | 			   attr = rpsl_object_get_attr(aut_num_obj, name);
3484 | 			   if ( attr )
3485 | 			   {
3486 | 		    	 value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3487 | 				 if ( value )
3488 | 				 {
3489 | 		    	   printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3490 | 				   free(value);
3491 | 				 }
3492 | 				 else
3493 | 		    	   printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3494 | 
3495 | 				 rpsl_attr_delete_list(attr);
3496 | 			   }
3497 | 			 }
3498 | 		   }
3499 | 		 }
3500 | 
3501 |          aut_num_maintainers = get_mnt_routes(aut_num_obj);
3502 |          if (aut_num_maintainers != NULL)
3503 | 		 {
3504 |            aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
3505 |            auth_return = authorise(aut_num_auth_vector, credentials, overriden);
3506 |            if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3507 | 		   {
3508 |              aut_num_auth_OK = TRUE;
3509 |            }
3510 | 		   else
3511 | 		   {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
3512 | 		     rpsl_attr_delete_list(aut_num_maintainers);
3513 |              return UP_HOF;
3514 |            }
3515 |          }
3516 | 		 else
3517 | 		 {/* aut_num_maintainers is NULL */
3518 |             aut_num_maintainers = get_mnt_lowers(aut_num_obj);
3519 |             if (aut_num_maintainers != NULL)
3520 | 			{
3521 |               aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
3522 |               auth_return = authorise(aut_num_auth_vector, credentials, overriden);
3523 |               if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3524 | 			  {
3525 |                 aut_num_auth_OK = TRUE;
3526 |               }
3527 | 			  else
3528 | 			  {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
3529 | 		        rpsl_attr_delete_list(aut_num_maintainers);
3530 |                 return UP_HOF; /* hierarchical authorisation failed */
3531 |               }
3532 |             }
3533 | 			else
3534 | 			{/* aut_num_maintainers is NULL */
3535 |               aut_num_maintainers = get_mntners(aut_num_obj);
3536 |               if (aut_num_maintainers != NULL)
3537 | 			  {
3538 |                 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
3539 |                 auth_return = authorise(aut_num_auth_vector, credentials, overriden);
3540 |                 if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3541 | 				{
3542 |                   aut_num_auth_OK = TRUE;
3543 |                 }
3544 | 				else
3545 | 				{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
3546 | 		          rpsl_attr_delete_list(aut_num_maintainers);
3547 |                   return UP_HOF; /* hierarchical authorisation failed */
3548 |                 }
3549 |               }
3550 | 			  else
3551 | 			  {/* aut_num_maintainers is NULL */
3552 |                 aut_num_auth_OK = TRUE;
3553 |               }
3554 |               
3555 |             }
3556 |          }
3557 |          rpsl_object_delete(aut_num_obj);
3558 | 
3559 |          if (aut_num_auth_OK)
3560 | 		 {
3561 |            /* now, we have to find an exact match for this route object. 
3562 |               If there is no exact match object, then we will go on to find
3563 |               less specific. */
3564 |            exact_match_routes_str = get_exact_match_routes(new_object);
3565 |            if (exact_match_routes_str != NULL)
3566 | 		   {
3567 |              /* there are one or more exact match routes */
3568 |              exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes_str);
3569 |              if ( exact_match_routes_maintainers )
3570 |              {
3571 |                /* the exact match(s) has some mnt-routes */
3572 |                exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
3573 |                if (exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL)
3574 | 			   {
3575 |                  /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
3576 | 		         rpsl_attr_delete_list(exact_match_routes_maintainers);
3577 |                  return UP_AUF; /* auth failed */
3578 |                }
3579 |                auth_return = authorise(exact_match_routes_auth_vector, credentials, overriden);
3580 |              }
3581 |              else
3582 |              {
3583 |                /* no mnt-routes so check the mnt-by of the exact match */
3584 |                exact_match_maintainers = get_mntners_from_list(exact_match_routes_str);
3585 |                exact_match_auth_vector = get_auth_vector(exact_match_maintainers);
3586 |                if (exact_match_maintainers != NULL && exact_match_auth_vector == NULL)
3587 | 			   {
3588 |                  /* then, the mntners in 'exact_match_maintainers' do not exist. Problem. */
3589 | 		         rpsl_attr_delete_list(exact_match_maintainers);
3590 |                  return UP_AUF; /* auth failed */
3591 |                }
3592 |                auth_return = authorise(exact_match_auth_vector, credentials, overriden);
3593 |              }
3594 |              if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3595 | 			 {
3596 |                saved_auth_return = auth_return;
3597 |                /* then, check mnt_bys of the route itself */
3598 |                new_mntners = get_mntners(new_object);
3599 |                new_auth_vector = get_auth_vector(new_mntners);
3600 |                if (new_mntners != NULL && new_auth_vector == NULL)
3601 | 			   {
3602 |                  /* then, the mntners in 'new_mntners' do not exist. Problem. */
3603 | 		         rpsl_attr_delete_list(new_mntners);
3604 |                  return UP_AUF; /* auth failed */
3605 |                }
3606 |                auth_return = authorise(new_auth_vector, credentials, overriden);
3607 | 		       if (new_auth_vector)
3608 |   	             g_slist_free(new_auth_vector);
3609 |                if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3610 |                  return UP_OKM;
3611 |                else
3612 | 	             return auth_return;
3613 |              }
3614 | 			 else
3615 | 			 { /*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
3616 |                return UP_HOF; /* hierarchical authorisation failed */
3617 |              }
3618 |            }
3619 | 		   else
3620 | 		   { /* exact_match_routes == NULL */
3621 |              /* then we have to look for less specific route objs */
3622 |              less_spec_routes_str = get_less_spec_routes(new_object);
3623 |              if (less_spec_routes_str != NULL)
3624 | 			 {
3625 |                less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes_str);
3626 |                less_spec_routes_mntners = g_list_concat(less_spec_routes_mntners, 
3627 |                                              get_mnt_lowers_from_list(less_spec_routes_str));
3628 |                less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
3629 |                if (less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL)
3630 | 			   {
3631 |                  /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
3632 | 		         rpsl_attr_delete_list(less_spec_routes_mntners);
3633 |                  return UP_AUF; /* auth failed */
3634 |                }
3635 |                if ( less_spec_routes_mntners != NULL )
3636 |                {
3637 |                  auth_return = authorise(less_spec_routes_auth_vector, credentials, overriden);
3638 |                  if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3639 | 			     {
3640 |                    saved_auth_return = auth_return;
3641 |                    /* then, check mnt_bys of the route itself */
3642 |                    new_mntners = get_mntners(new_object);
3643 |                    new_auth_vector = get_auth_vector(new_mntners);
3644 |                    if (new_mntners != NULL && new_auth_vector == NULL)
3645 | 				   {
3646 |                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3647 | 		             rpsl_attr_delete_list(new_mntners);
3648 |                      return UP_AUF; /* auth failed */
3649 |                    }
3650 |                    auth_return = authorise(new_auth_vector, credentials, overriden);
3651 | 		           if (new_auth_vector)
3652 |   	                 g_slist_free(new_auth_vector);
3653 |                    if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM )
3654 |                      return UP_OKM;
3655 |                    else
3656 | 	                 return auth_return;
3657 |                  }
3658 | 			     else
3659 | 			     { /*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
3660 |                    return UP_HOF; /* hierarchical authorisation failed */
3661 |                  }
3662 |                }
3663 |                else
3664 |                {
3665 |                  /* there are no mnt-routes or mnt-lower in less specific route objs */
3666 |                  /* check mnt-by of less specific route objs */
3667 |                  less_spec_routes_mntners = get_mntners_from_list(less_spec_routes_str);
3668 |                  less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
3669 |                  if (less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL)
3670 | 			     {
3671 |                    /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
3672 | 		           rpsl_attr_delete_list(less_spec_routes_mntners);
3673 |                    return UP_AUF; /* auth failed */
3674 |                  }
3675 |                  auth_return = authorise(less_spec_routes_auth_vector, credentials, overriden);
3676 |                  if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3677 | 			     {
3678 |                    saved_auth_return = auth_return;
3679 |                    /* then, check mnt_bys of the route itself */
3680 |                    new_mntners = get_mntners(new_object);
3681 |                    new_auth_vector = get_auth_vector(new_mntners);
3682 |                    if (new_mntners != NULL && new_auth_vector == NULL)
3683 | 				   {
3684 |                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3685 | 		             rpsl_attr_delete_list(new_mntners);
3686 |                      return UP_AUF; /* auth failed */
3687 |                    }
3688 |                    auth_return = authorise(new_auth_vector, credentials, overriden);
3689 | 		           if (new_auth_vector)
3690 |   	                 g_slist_free(new_auth_vector);
3691 |                    if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3692 |                      return UP_OKM;
3693 |                    else
3694 | 	                 return auth_return;
3695 |                  }
3696 | 			     else
3697 | 			     { /*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
3698 |                    return UP_HOF; /* hierarchical authorisation failed */
3699 |                  }
3700 |                }
3701 |              }
3702 | 			 else
3703 | 			 {  /* less_spec_routes == NULL */
3704 |                /* so, we have to get the exact match inetnum */
3705 |                exact_match_inetnum_str = get_exact_match_inetnum(new_object);
3706 |                if (exact_match_inetnum_str != NULL)
3707 | 			   {
3708 | 				 exact_match_inetnum_obj = rpsl_object_init(exact_match_inetnum_str);
3709 | 				 if (tracing)
3710 | 				 {
3711 |     			   if ( rpsl_object_has_error(exact_match_inetnum_obj, RPSL_ERRLVL_ERROR) )
3712 | 				   {
3713 | 					 /* thre was an error during the parsing */
3714 | 					 name = rpsl_object_get_class(exact_match_inetnum_obj);
3715 | 					 if ( name )
3716 | 					 {
3717 | 					   attr = rpsl_object_get_attr(exact_match_inetnum_obj, name);
3718 | 					   if ( attr )
3719 | 					   {
3720 | 		    			 value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3721 | 						 if ( value )
3722 | 						 {
3723 | 		    			   printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3724 | 						   free(value);
3725 | 						 }
3726 | 						 else
3727 | 		    			   printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3728 | 
3729 | 						 rpsl_attr_delete_list(attr);
3730 | 					   }
3731 | 					 }
3732 | 				   }
3733 | 				 }
3734 | 
3735 |                  exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum_obj);
3736 | 				 exact_match_inetnum_mnt_bys = get_mntners(exact_match_inetnum_obj);
3737 | 				 rpsl_object_delete(exact_match_inetnum_obj);
3738 | 
3739 |                  exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
3740 |                  if (exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL)
3741 | 				 {
3742 |                    /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
3743 | 		           rpsl_attr_delete_list(exact_match_inetnum_mnt_routes);
3744 |                    return UP_AUF; /* auth failed */
3745 |                  }
3746 | 
3747 | 				 /* if there are mnt_routes in the exact match inetnum */
3748 | 				 if (exact_match_inetnum_mnt_routes != NULL)
3749 | 				 {
3750 | 				   auth_return = authorise(exact_match_inetnum_auth_vector, credentials, overriden);
3751 | 				   if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3752 | 				   {
3753 |                      saved_auth_return = auth_return;
3754 | 					 /* then, check mnt_bys of the route itself */
3755 | 					 new_mntners = get_mntners(new_object);
3756 | 					 new_auth_vector = get_auth_vector(new_mntners);
3757 | 					 if (new_mntners != NULL && new_auth_vector == NULL)
3758 | 					 {
3759 | 					   /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3760 | 		               rpsl_attr_delete_list(new_mntners);
3761 | 					   return UP_AUF; /* auth failed */
3762 | 					 }
3763 |                      auth_return = authorise(new_auth_vector, credentials, overriden);
3764 | 		             if (new_auth_vector)
3765 |   	                   g_slist_free(new_auth_vector);
3766 |                      if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3767 |                        return UP_OKM;
3768 |                      else
3769 | 	                   return auth_return;
3770 | 				   }
3771 | 				   else
3772 | 				   {
3773 | 					 return UP_HOF; /* hierarchical authorisation failed */
3774 | 				   }
3775 | 				 }
3776 | 				 else
3777 | 				 { /* if there was no mnt_routes in the exact match inetnum, then use mnt-by of it */
3778 | 				   exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_bys);
3779 | 				   if (exact_match_inetnum_mnt_bys != NULL && exact_match_inetnum_auth_vector == NULL)
3780 | 				   {
3781 | 					 /* then, the mntners in 'exact_match_inetnum_mnt_bys' do not exist. Problem. */
3782 | 		             rpsl_attr_delete_list(exact_match_inetnum_mnt_bys);
3783 |                      return UP_AUF; /* auth failed */
3784 |                    }
3785 |                    
3786 |                    /* check mnt-by of exact match inetnum */
3787 |                    auth_return = authorise(exact_match_inetnum_auth_vector, credentials, overriden);
3788 |                    if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3789 | 				   {
3790 |                      saved_auth_return = auth_return;
3791 |                      /* then, check mnt_bys of the route itself */
3792 |                      new_mntners = get_mntners(new_object);
3793 |                      new_auth_vector = get_auth_vector(new_mntners);
3794 |                      if (new_mntners != NULL && new_auth_vector == NULL)
3795 | 				     {
3796 |                        /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3797 | 		               rpsl_attr_delete_list(new_mntners);
3798 |                        return UP_AUF; /* auth failed */
3799 |                      }
3800 |                      auth_return = authorise(new_auth_vector, credentials, overriden);
3801 | 		             if (new_auth_vector)
3802 |   	                   g_slist_free(new_auth_vector);
3803 |                      if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3804 |                        return UP_OKM;
3805 |                      else
3806 | 	                   return auth_return;
3807 |                    }
3808 | 				   else
3809 | 				   {
3810 |                      return UP_HOF; /* hierarchical authorisation failed */
3811 |                    }
3812 |                  }
3813 |                }
3814 | 			   else
3815 | 			   {/* exact_match_inetnum == NULL */
3816 |                  /* then, we will try to find less spec inetnums */
3817 |                  less_spec_inetnum_str = get_less_spec_inetnum(new_object);
3818 |                  if (less_spec_inetnum_str != NULL)
3819 | 				 {
3820 | 				   less_spec_inetnum_obj = rpsl_object_init(less_spec_inetnum_str);
3821 | 				   if (tracing)
3822 | 				   {
3823 |     				 if ( rpsl_object_has_error(less_spec_inetnum_obj, RPSL_ERRLVL_ERROR) )
3824 | 					 {
3825 | 					   /* thre was an error during the parsing */
3826 | 					   name = rpsl_object_get_class(less_spec_inetnum_obj);
3827 | 					   if ( name )
3828 | 					   {
3829 | 						 attr = rpsl_object_get_attr(less_spec_inetnum_obj, name);
3830 | 						 if ( attr )
3831 | 						 {
3832 | 		    			   value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
3833 | 						   if ( value )
3834 | 						   {
3835 | 		    				 printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
3836 | 							 free(value);
3837 | 						   }
3838 | 						   else
3839 | 		    				 printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
3840 | 
3841 | 						   rpsl_attr_delete_list(attr);
3842 | 						 }
3843 | 					   }
3844 | 					 }
3845 | 				   }
3846 | 
3847 |                    less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum_obj);
3848 |                    less_spec_inetnum_mntners = g_list_concat(less_spec_inetnum_mntners, 
3849 |                                   get_mnt_lowers(less_spec_inetnum_obj));
3850 |                    less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
3851 | 
3852 | 				   less_spec_inetnum_mnt_bys = get_mntners(less_spec_inetnum_obj);
3853 | 
3854 | 				   rpsl_object_delete(less_spec_inetnum_obj);
3855 | 
3856 |                    if (less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL)
3857 | 				   {
3858 |                      /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
3859 | 		             rpsl_attr_delete_list(less_spec_inetnum_mntners);
3860 |                      return UP_AUF; /* auth failed */
3861 |                    }
3862 | 				   if (less_spec_inetnum_mntners != NULL)
3863 | 				   { /* if there are mntners in mnt-lower and/or mnt-routes */
3864 | 					 auth_return = authorise(less_spec_inetnum_auth_vector, credentials, overriden);
3865 | 					 if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
3866 | 					 {
3867 |                        saved_auth_return = auth_return;
3868 | 					   /* then, check mnt_bys of the route itself */
3869 | 					   new_mntners = get_mntners(new_object);
3870 | 					   new_auth_vector = get_auth_vector(new_mntners);
3871 | 					   if (new_mntners != NULL && new_auth_vector == NULL)
3872 | 					   {
3873 | 						 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3874 | 		                 rpsl_attr_delete_list(new_mntners);
3875 | 						 return UP_AUF; /* auth failed */
3876 | 					   }
3877 |                        auth_return = authorise(new_auth_vector, credentials, overriden);
3878 | 		               if (new_auth_vector)
3879 |   	                     g_slist_free(new_auth_vector);
3880 |                        if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
3881 |                          return UP_OKM;
3882 |                        else
3883 | 	                     return auth_return;
3884 | 					 }
3885 | 					 else
3886 | 					 { /* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
3887 | 					   return UP_HOF; /* hierarchical authorisation failed */
3888 | 					 }
3889 | 				   }
3890 | 				   else
3891 | 				   { /* there isn't any mnt-lower or mnt-routes in the less spec inetnum */
3892 | 						 /* so we must use mnt-by of less spec inetum */
3893 | 					 less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mnt_bys);
3894 | 					 if (less_spec_inetnum_mnt_bys != NULL && less_spec_inetnum_auth_vector == NULL)
3895 | 					 {
3896 | 					   /* then, the mntners in 'less_spec_inetnum_mnt_bys' do not exist. Problem. */
3897 | 
3898 | 		               rpsl_attr_delete_list(less_spec_inetnum_mnt_bys);
3899 |                        return UP_AUF; /* auth failed */
3900 |                      }
3901 | 					 auth_return = authorise(less_spec_inetnum_auth_vector, credentials, overriden);
3902 | 					 if (auth_return == UP_AUTH_OK  ||  auth_return == UP_OKM)
3903 | 					 {
3904 |                        saved_auth_return = auth_return;
3905 | 					   /* then, check mnt_bys of the route itself */
3906 | 					   new_mntners = get_mntners(new_object);
3907 | 					   new_auth_vector = get_auth_vector(new_mntners);
3908 | 					   if (new_mntners != NULL && new_auth_vector == NULL)
3909 | 					   {
3910 | 						 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3911 | 		                 rpsl_attr_delete_list(new_mntners);
3912 | 						 return UP_AUF; /* auth failed */
3913 | 					   }
3914 |                        auth_return = authorise(new_auth_vector, credentials, overriden);
3915 | 		               if (new_auth_vector)
3916 |   	                     g_slist_free(new_auth_vector);
3917 |                        if (auth_return == UP_AUTH_OK  && saved_auth_return == UP_OKM)
3918 |                          return UP_OKM;
3919 |                        else
3920 | 	                     return auth_return;
3921 | 					 }
3922 | 					 else
3923 | 					 {
3924 | 					   return UP_HOF; /* hierarchical authorisation failed */
3925 | 					 }
3926 |                    }
3927 |                  }
3928 | 				 else
3929 | 				 {/* less_spec_inetnum == NULL */
3930 |                    /* now that we couldn't find any route or inetnum object
3931 |                       to be used in authentication. So, only if the auth is
3932 |                       overriden the object will be created. */
3933 |                    if (overriden)
3934 | 				   {
3935 |                      return UP_AUTH_OK; 
3936 |                    }
3937 | 				   else
3938 | 				   {
3939 |                      return UP_HOF; /* hierarchical authorisation failed */
3940 |                    }
3941 |                  }
3942 |                }
3943 |              }
3944 |            }
3945 |          }
3946 | 		 else
3947 | 		 {/* ! aut_num_auth_OK */
3948 |            return UP_HOF; /* hierarchical auth failed */
3949 |          }
3950 |        }
3951 |           
3952 |      }
3953 | 	 else if ( new_object != NULL && old_object != NULL )
3954 | 	 { /* this is an update */
3955 |        old_mntners = get_mntners(old_object);
3956 |        old_auth_vector = get_auth_vector(old_mntners);
3957 |        if (old_mntners != NULL && old_auth_vector == NULL)
3958 | 	   {
3959 |          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
3960 | 		 rpsl_attr_delete_list(old_mntners);
3961 |          return UP_AUF; /* auth failed */
3962 |        }
3963 |        if (old_auth_vector)
3964 | 	   { /* if we have mntners in the old object, use them */
3965 |          auth_return = authorise(old_auth_vector, credentials, overriden);
3966 | 	     g_slist_free(old_auth_vector);
3967 | 	     return auth_return;
3968 |        }
3969 | 	   else
3970 | 	   {
3971 |          new_mntners = get_mntners(new_object);
3972 |          new_auth_vector = get_auth_vector(new_mntners);
3973 |          if (new_mntners != NULL && new_auth_vector == NULL)
3974 | 		 {
3975 |            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
3976 | 		   rpsl_attr_delete_list(new_mntners);
3977 |            return UP_AUF; /* auth failed */
3978 |          }
3979 |          auth_return = authorise(new_auth_vector, credentials, overriden);
3980 | 		 if (new_auth_vector)
3981 |   	       g_slist_free(new_auth_vector);
3982 | 	     return auth_return;
3983 |        }
3984 |      }
3985 | 	 else
3986 | 	 { /* both are NULL, mustn't happen */
3987 |          if (tracing)
3988 | 		 {
3989 |            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
3990 |          }
3991 |          return UP_INT; /* internal error */
3992 |      }
3993 |    }
3994 | 
3995 | 
3996 |    /*  
3997 |     *  Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types 
3998 |     */
3999 |    else if (strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
4000 |            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ||
4001 |            strcmp(type,"route-set")    == 0 )
4002 |    {
4003 |      if ( new_object == NULL && old_object != NULL )
4004 | 	 { /* the object is to be deleted */
4005 |        old_mntners = get_mntners(old_object);
4006 |        old_auth_vector = get_auth_vector(old_mntners);
4007 |        if (old_mntners != NULL && old_auth_vector == NULL)
4008 | 	   {
4009 |          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
4010 | 		 rpsl_attr_delete_list(old_mntners);
4011 |          return UP_AUF; /* auth failed */
4012 |        }
4013 |        auth_return = authorise(old_auth_vector, credentials, overriden);
4014 | 	   g_slist_free(old_auth_vector);
4015 | 	   return auth_return;
4016 |      }
4017 | 	 else if ( new_object != NULL && old_object == NULL )
4018 | 	 { /* the object is to be created */
4019 |         set_name = get_search_key(new_object, type);
4020 |        if (strstr(set_name,":") == NULL )
4021 | 	   { /* if the name is _not_ hierarchical */
4022 |          new_mntners = get_mntners(new_object);
4023 |          new_auth_vector = get_auth_vector(new_mntners);
4024 |          if (new_mntners != NULL && new_auth_vector == NULL)
4025 | 		 {
4026 |            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
4027 | 		   rpsl_attr_delete_list(new_mntners);
4028 |            return UP_AUF; /* auth failed */
4029 |          }
4030 |          auth_return = authorise(new_auth_vector, credentials, overriden);
4031 | 		 if (new_auth_vector)
4032 |   	       g_slist_free(new_auth_vector);
4033 | 	     return auth_return;
4034 |        }
4035 | 	   else
4036 | 	   { /* the name is hierarchical */
4037 |          less_specific_object_str = get_less_specific_set(new_object, type);
4038 |          if (less_specific_object_str != NULL)
4039 | 		 { /* such an object exists */
4040 | 		   less_specific_obj = rpsl_object_init(less_specific_object_str);
4041 | 		   if (tracing)
4042 | 		   {
4043 |     		 if ( rpsl_object_has_error(less_specific_obj, RPSL_ERRLVL_ERROR) )
4044 | 			 {
4045 | 			   /* thre was an error during the parsing */
4046 | 			   name = rpsl_object_get_class(less_specific_obj);
4047 | 			   if ( name )
4048 | 			   {
4049 | 				 attr = rpsl_object_get_attr(less_specific_obj, name);
4050 | 				 if ( attr )
4051 | 				 {
4052 | 		    	   value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
4053 | 				   if ( value )
4054 | 				   {
4055 | 		    		 printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
4056 | 					 free(value);
4057 | 				   }
4058 | 				   else
4059 | 		    		 printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
4060 | 
4061 | 				   rpsl_attr_delete_list(attr);
4062 | 				 }
4063 | 			   }
4064 | 			 }
4065 | 		   }
4066 | 
4067 |            less_specific_object_type = rpsl_object_get_class(less_specific_obj);
4068 | 
4069 |            if (strcmp(less_specific_object_type, "aut-num") == 0)
4070 | 		   { /* if this is an aut-num object */
4071 |              less_specific_mnt_lowers = get_mnt_lowers(less_specific_obj);
4072 |              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
4073 |              if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
4074 | 			 {
4075 |                /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
4076 | 		      rpsl_attr_delete_list(less_specific_mnt_lowers);
4077 |               rpsl_object_delete(less_specific_obj);
4078 |               return UP_AUF; /* auth failed */
4079 |              }
4080 |              if (less_specific_auth_vector != NULL)
4081 | 			 {
4082 |                auth_return = authorise(less_specific_auth_vector, credentials, overriden);
4083 | 	           g_slist_free(less_specific_auth_vector);
4084 |                rpsl_object_delete(less_specific_obj);
4085 | 	           return auth_return;
4086 |              }
4087 | 			 else
4088 | 			 { /* the less specific object doesn't contain any mnt-lower */
4089 |                less_specific_mntners = get_mntners(less_specific_obj);
4090 |                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
4091 |                if (less_specific_mntners != NULL && less_specific_auth_vector == NULL)
4092 | 			   {
4093 |                  /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
4094 | 		         rpsl_attr_delete_list(less_specific_mntners);
4095 |                  rpsl_object_delete(less_specific_obj);
4096 |                  return UP_AUF; /* auth failed */
4097 |                }
4098 |                if (less_specific_auth_vector != NULL)
4099 | 			   {  /* less spec object has some mnt-by attribs, 
4100 |                                                         use them  */
4101 |                    auth_return = authorise(less_specific_auth_vector, credentials, overriden);
4102 | 	               g_slist_free(less_specific_auth_vector);
4103 |                    rpsl_object_delete(less_specific_obj);
4104 | 	               return auth_return;
4105 |                }
4106 | 			   else
4107 | 			   { /* the less specific object doesn't contain any mnt-by either */
4108 |                  if (overriden)
4109 | 				 {
4110 |                    rpsl_object_delete(less_specific_obj);
4111 |                    return UP_AUTH_OK; 
4112 |                  }
4113 | 				 else
4114 | 				 {
4115 |                    rpsl_object_delete(less_specific_obj);
4116 |                    return UP_HOF; /* hierarchical authorisation failed */
4117 |                  }
4118 |                }
4119 |              }
4120 |            }
4121 | 		   else
4122 | 		   { /* this is _not_ an aut-num object*/
4123 |              less_specific_mntners = get_mntners(less_specific_obj);
4124 |              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
4125 |              if (less_specific_mntners != NULL && less_specific_auth_vector == NULL)
4126 | 			 {
4127 |                /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
4128 | 		       rpsl_attr_delete_list(less_specific_mntners);
4129 |                rpsl_object_delete(less_specific_obj);
4130 |                return UP_AUF; /* auth failed */
4131 |              }
4132 |              if (less_specific_auth_vector != NULL )
4133 | 			 { /* the set obj has some mnt-by attribs */
4134 |                auth_return = authorise(less_specific_auth_vector, credentials, overriden);
4135 | 	           g_slist_free(less_specific_auth_vector);
4136 |                rpsl_object_delete(less_specific_obj);
4137 | 	           return auth_return;
4138 |              }
4139 | 			 else
4140 | 			 {
4141 |                if (overriden)
4142 | 			   {
4143 |                  rpsl_object_delete(less_specific_obj);
4144 |                  return UP_AUTH_OK; 
4145 |                }
4146 | 			   else
4147 | 			   {
4148 |                  rpsl_object_delete(less_specific_obj);
4149 |                  return UP_HOF; /* hierarchical authorisation failed */
4150 |                }
4151 |              }
4152 |            }
4153 |          }
4154 | 		 else
4155 | 		 { /* we don't have a less specific of this set object in the DB  */
4156 |            return UP_HOF; /* hierarchical authorisation failed */
4157 |          }
4158 |        }
4159 |      }
4160 | 	 else if ( new_object != NULL && old_object != NULL )
4161 | 	 { /* this is an update */
4162 |        old_mntners = get_mntners(old_object);
4163 |        old_auth_vector = get_auth_vector(old_mntners);
4164 |        if (old_mntners != NULL && old_auth_vector == NULL)
4165 | 	   {
4166 |          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
4167 | 		 rpsl_attr_delete_list(old_mntners);
4168 |          return UP_AUF; /* auth failed */
4169 |        }
4170 |        if (old_auth_vector)
4171 | 	   { /* if we have mntners in the old object, use them */
4172 |          auth_return = authorise(old_auth_vector, credentials, overriden);
4173 | 	     g_slist_free(old_auth_vector);
4174 | 	     return auth_return;
4175 |        }
4176 | 	   else
4177 | 	   {
4178 |          new_mntners = get_mntners(new_object);
4179 |          new_auth_vector = get_auth_vector(new_mntners);
4180 |          if (new_mntners != NULL && new_auth_vector == NULL)
4181 | 		 {
4182 |            /* then, the mntners in 'new_mntners' do not exist. Problem. */
4183 | 		   rpsl_attr_delete_list(new_mntners);
4184 |            return UP_AUF; /* auth failed */
4185 |          }
4186 |          auth_return = authorise(new_auth_vector, credentials, overriden);
4187 | 		 if (new_auth_vector)
4188 |   	       g_slist_free(new_auth_vector);
4189 | 	     return auth_return;
4190 |        }
4191 |      }
4192 | 	 else
4193 | 	 { /* both are NULL, mustn't happen */
4194 |          if (tracing)
4195 | 		 {
4196 |            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
4197 |          }
4198 |          return UP_INT; /* internal error */
4199 |      }
4200 | 
4201 |    }
4202 |    else
4203 |    { /* We exhausted all object classes. If we are here, then there is a problem */
4204 |      printf("check_auth: This type '%s' is unknown\n", type);
4205 |      return UP_NIY; /* not implemented yet */
4206 |    }
4207 |    return UP_AUF; /* if we come to this point, then auth failed */ 
4208 | }
4209 | 
4210 | 
4211 | 
4212 | /* Gets the old version of the given "arg" object, which is in char * format
4213 |    and returns the old version again in char * format */
4214 | 
4215 | char * get_old_version(rpsl_object_t *object, char * arg)
4216 | {
4217 |     const char *type=NULL;
4218 | 	char *lctype = NULL;
4219 | 	char *primary_search_key = NULL, *search_string = NULL;
4220 |     char *result = NULL, *origin = NULL, *nic_hdl = NULL;
4221 |     
4222 |     type = rpsl_object_get_class(object);
4223 | 	lctype = strdup(type);
4224 | 	g_strdown(lctype);
4225 | 
4226 |     primary_search_key = get_search_key(object, lctype);
4227 |     if ( primary_search_key == NULL )
4228 |     {
4229 |       if(tracing)
4230 |       {
4231 |         printf("type=%s\n", type);
4232 |         printf("primary_search_key is NULL\n");
4233 |       }
4234 | 	  return NULL;
4235 | 	}
4236 | 
4237 |     if(tracing) 
4238 | 	{
4239 |       printf("TRACING: type= %s\n", type);
4240 |       printf("TRACING: primary_search_key= %s\n", primary_search_key);
4241 |     }
4242 | 
4243 |     /* if the object is a pn or a ro object, then get all pn/ro's with the same NIC hdl */
4244 |     if ( strcmp(lctype,"person") == 0 || strcmp(lctype,"role") == 0 )
4245 | 	{
4246 |       /* prepare the search string */
4247 |       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T -s ")
4248 |                                           +strlen(current_source)+ strlen("person,role") + 2);
4249 |       sprintf(search_string, "-x -R -r -Tperson,role -s %s %s", current_source, primary_search_key);
4250 |     }
4251 | 	else
4252 | 	{
4253 |       /* prepare the search string */
4254 |       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T -s ")
4255 |                                           +strlen(current_source)+ strlen(lctype) + 2);
4256 |       sprintf(search_string, "-x -R -r -T%s -s %s %s",lctype, current_source, primary_search_key);
4257 |     }
4258 | 	
4259 |     result = send_and_get(query_host, query_port, search_string);
4260 |     if(tracing) 
4261 | 	{
4262 |       printf("TRACING: send_and_get returned with search %s result %s\n", search_string, result);
4263 |     }
4264 | 	free(search_string);
4265 | 	free(primary_search_key);
4266 | 	if ( result == NULL )
4267 | 	  return NULL;
4268 | 
4269 |     /* and here, we must filter the 'result' with NIC handle */
4270 |     if ( strcmp(lctype,"person") == 0 )
4271 | 	{
4272 |       if(tracing) 
4273 | 	  {
4274 |         printf("TRACING: This is a person\n");
4275 |       }
4276 |       /* if this is a person, then we must filter out the persons with different
4277 |          nic-hdl attributes (since it is possible to have this NIC hdl in the name
4278 |          of a person object, and whois will return that object too) */
4279 |       nic_hdl = get_search_key(object, "nic-hdl");
4280 |       if(tracing) 
4281 | 	  {
4282 |         printf("TRACING: Got nic-hdl of person: %s\n", nic_hdl);
4283 |       }
4284 |       result = up_filter_out_diff_nichdls(result, nic_hdl);  
4285 |       if(tracing) 
4286 | 	  {
4287 |         printf("TRACING: Filtered person\n");
4288 |       }
4289 | 	  free(nic_hdl);
4290 |     }
4291 | 
4292 |     /* also, we must filter the 'result' with NIC handle for roles */
4293 |     if(strcmp(type,"role") == 0)
4294 | 	{
4295 |       if(tracing) 
4296 | 	  {
4297 |         printf("TRACING: This is a role\n");
4298 |       }
4299 |       /* if this is a role, then we must filter out the roles with different
4300 |          nic-hdl attributes (since it is possible to have this NIC hdl in the name
4301 |          of a role object, and whois will return that object too) */
4302 |       nic_hdl = get_search_key(object, "nic-hdl");
4303 |       if(tracing) 
4304 | 	  {
4305 |         printf("TRACING: Got nic-hdl of role: %s\n", nic_hdl);
4306 |       }
4307 |       result = up_filter_out_diff_nichdls(result, nic_hdl);  
4308 |       if(tracing) 
4309 | 	  {
4310 |         printf("TRACING: Filtered role\n");
4311 |       }
4312 | 	  free(nic_hdl);
4313 |     }
4314 | 
4315 |     if(strcmp(type,"route") == 0)
4316 | 	{
4317 |       if(tracing) 
4318 | 	  {
4319 |         printf("TRACING: This is a route\n");
4320 |       }
4321 |       /* if this is a route, then we must filter out the routes with different
4322 |          origin attributes */
4323 |       origin = get_search_key(object, "origin");
4324 |       if(tracing) 
4325 | 	  {
4326 |         printf("TRACING: Got origin of route: %s\n", origin);
4327 |       }
4328 |       result = up_filter_out_diff_origins(result, origin);  
4329 |       if(tracing) 
4330 | 	  {
4331 |         printf("TRACING: Filtered routes\n");
4332 |       }
4333 | 	  free(origin);
4334 |     }
4335 |     
4336 |     /* count the objects */
4337 |     if(count_objects(result) == 0)
4338 | 	{
4339 |       result = NULL; /* we don't have such an object */
4340 |     }
4341 | 	else if(count_objects(result) == 1)
4342 | 	{
4343 |       result = take_object(result);
4344 |       if(tracing) 
4345 | 	  {
4346 |       printf("TRACING: Take_object returned ***%s\n", result);
4347 |       }
4348 |     }
4349 | 	else
4350 | 	{ /* we have more than one objects, error! */
4351 |       result = NULL;
4352 |     }
4353 | 	
4354 |     return result;
4355 | }
4356 | 
4357 | 
4358 | 
4359 | 
4360 | /* Gets a credentials_struct whose 'from' field will be filled in and
4361 |    the mail header. Finds the 'From:' line in the header and sets
4362 |    the 'from' field to this line (all line, including the 'From:' string,
4363 |    since some users have put regexps which match the whole line in their
4364 |    'auth' attributes.) */
4365 | void process_mail_header(credentials_struct * credentials_ptr, char * arg)
4366 | {
4367 |   char * header = strdup(arg);
4368 |   char * temp = (char *)malloc(strlen(header));
4369 | 
4370 |   while (index(header, '\n') != NULL)
4371 |   {
4372 |     temp = strdup(header);
4373 |     temp[index(temp, '\n') - temp] = '\0';
4374 |     if (strstr(temp, "From:") == temp)
4375 | 	{
4376 |       if (tracing)
4377 | 	  {
4378 |         printf("TRACING: process_mail_header: Assigning %s\n", temp);
4379 |       }
4380 |       credentials_ptr->from = strdup(temp);
4381 |       free(temp);
4382 |       return;
4383 |     }
4384 |     header = header + (index(header, '\n') - header + 1);
4385 |   }
4386 |   free(temp);
4387 | }
4388 | 
4389 | 
4390 | 
4391 | void up_string_pack(char *dest, const char *source)
4392 | {
4393 |   if(tracing) 
4394 |   {
4395 |     printf("TRACING: up_string_pack running\n");
4396 |   }
4397 | 
4398 | /*----------------------------------------------------------------------*\
4399 | 
4400 | *  Function to rewrite a line of text with only one blankspace between  *
4401 | *  each word.
4402 | *
4403 | \*----------------------------------------------------------------------*/
4404 | /*
4405 |  * This while loop continues until the NULL character is copied into
4406 |  * the destination string.  If a tab character is copied into the
4407 |  * destination string, it is replaced with a blank-space character.
4408 |  *
4409 |  * Multiple blank-space and/or tab characters are skipped in the source
4410 |  * string until any other character is found.
4411 |  */
4412 | 
4413 |   while (1)
4414 |   {
4415 |     *dest = *source;
4416 | 
4417 |     if (*dest == '\t')
4418 |             (*dest = ' ');
4419 | 
4420 |     /* Exit if have copied the end of the string. */
4421 |     if (*dest == '\0')
4422 |             return;
4423 | 
4424 | /*
4425 | * If the source character was a blank-space or a tab, move to the next
4426 | * source character.  While the source character is a blank-space or a
4427 | * tab, move to the next character (i.e. ignore these characters).  When
4428 | * any other character is found in the source string, move to the next
4429 | * element of the destination string.
4430 | *
4431 | * Otherwise, simultaneously, move to the next elements of the destination
4432 | * and the source strings.
4433 | */
4434 | 
4435 |     if ( (*source == ' ') || (*source == '\t') )
4436 |     {
4437 |         ++source;
4438 |         while ( (*source == ' ') || (*source == '\t') )
4439 |                 {
4440 |                 ++source;
4441 |                 }
4442 | 
4443 |         ++dest;
4444 |     }
4445 |     else
4446 |     {
4447 |         ++dest;
4448 |         ++source;
4449 |     }
4450 |   }
4451 | }
4452 | 
4453 | 
4454 | /* replaces the erase_str occurences with insert_str in str (which is a ptr to GString) */
4455 | char * UP_replace_strings(char * str, const char * erase_str, const char * insert_str)
4456 | {
4457 |   GString * g_str;  
4458 |   int pos;
4459 |   char * result_str;
4460 |   
4461 |   /* erase_str mustn't be NULL */
4462 |   assert(erase_str != NULL);
4463 |   
4464 |   /* if insert str is NULL, make it empty string */
4465 |   if(insert_str == NULL)
4466 |   {
4467 |     insert_str = strdup(""); 
4468 |   }
4469 |   
4470 |   g_str = g_string_new(str);
4471 |   
4472 |   /* replace erase_str with insert_str */
4473 |   while(strstr(g_str->str, erase_str) != NULL)
4474 |   {
4475 |     pos = strstr(g_str->str, erase_str) - g_str->str;
4476 |     g_str = g_string_erase(g_str, pos, strlen(erase_str));
4477 |     if(insert_str != NULL)
4478 | 	{
4479 |       g_str = g_string_insert(g_str, pos, insert_str);
4480 |     }
4481 |   }
4482 | 
4483 |   /* save the result string */
4484 |   result_str = strdup(g_str->str);
4485 | 
4486 |   /* free the GString structure (TRUE means 'also free the char string') */
4487 |   g_string_free(g_str, TRUE);
4488 | 
4489 |   return result_str;
4490 | }
4491 | 
4492 | 
4493 | 
4494 | /* replaces the erase_str occurences with insert_str in g_str (which is a ptr to GString) */
4495 | GString * UP_replace_GStrings(GString * g_str, const char * erase_str, const char * insert_str)
4496 | {
4497 |   int pos;
4498 |   
4499 |   if (insert_str == NULL)
4500 |   { /* then don't do anything */
4501 |     return g_str;
4502 |   }
4503 |    
4504 |   /* replace erase_str with insert_str */
4505 |   while (strstr(g_str->str, erase_str) != NULL)
4506 |   {
4507 |     pos = strstr(g_str->str, erase_str) - g_str->str;
4508 |     g_str = g_string_erase(g_str, pos, strlen(erase_str));
4509 |     g_str = g_string_insert(g_str, pos, insert_str);
4510 |   }
4511 |   return g_str;
4512 | }
4513 | 
4514 | 
4515 | 
4516 | /* looks if two objects are identical or not.
4517 |     Takes two objects, one as char *, the other as
4518 | 	a parsed object, and returns 1 if
4519 |     they are identical, returns 0 if not.
4520 | 
4521 |     Algorithm is very simple: All strings of tabs and 
4522 |     white spaces are collapsed into a single white space,
4523 |     and then the strings are compared (strcmp) */
4524 | int identical(const char * old_version, rpsl_object_t *object)
4525 | {
4526 |   char * arg1 = strdup(old_version);
4527 |   char * arg2 = NULL;
4528 |   rpsl_object_t *object2;
4529 |   rpsl_error_t error;
4530 |   int result = 0;
4531 |   char *temp1, *temp2; 
4532 |   char *temp;
4533 |   
4534 |   object2 = rpsl_object_copy(object);
4535 |   rpsl_object_remove_attr_name(object2, "delete", &error);
4536 |   rpsl_object_remove_attr_name(object2, "override", &error);
4537 |   arg2 = rpsl_object_get_text(object2,RPSL_STD_COLUMN);
4538 | 
4539 |   arg1 = g_strstrip(arg1);
4540 |   arg2 = g_strstrip(arg2);
4541 | 
4542 |   /* convert tabs to white spaces */
4543 |   arg1 = g_strdelimit(arg1, "\t", ' ');
4544 |   arg2 = g_strdelimit(arg2, "\t", ' ');
4545 |   
4546 |   temp1 = (char *)malloc(strlen(arg1) + 1); 
4547 |   temp2 = (char *)malloc(strlen(arg2) + 1);
4548 |   up_string_pack(temp1, arg1);
4549 |   up_string_pack(temp2, arg2);
4550 | 
4551 |   /* if there are still \r's at the end of strings, remove them */
4552 |   if((temp1[strlen(temp1) - 1]) == '\r')
4553 |   {
4554 |     temp1[strlen(temp1) - 1] = '\0';
4555 |   }
4556 |   if((temp2[strlen(temp2) - 1]) == '\r')
4557 |   {
4558 |     temp2[strlen(temp2) - 1] = '\0';
4559 |   }
4560 | 
4561 |   /* there may be white spaces at the end of the strings now, remove them */
4562 |   if((temp1[strlen(temp1) - 1]) == ' ')
4563 |   {
4564 |     temp1[strlen(temp1) - 1] = '\0';
4565 |   }
4566 |   if((temp2[strlen(temp2) - 1]) == ' ')
4567 |   {
4568 |     temp2[strlen(temp2) - 1] = '\0';
4569 |   }
4570 | 
4571 |   /* remove the white spaces just before the EOLs (since this is not taken care of by
4572 |      the up_string_pack func) */
4573 |   temp = UP_replace_strings(temp1, " \n", "\n");
4574 |   free(temp1);
4575 |   temp1 = temp;
4576 | 
4577 |   temp = UP_replace_strings(temp2, " \n", "\n");
4578 |   free(temp2);
4579 |   temp2 = temp;
4580 | 
4581 |   result = strcmp(temp1, temp2);
4582 |   if(tracing){
4583 |     printf("TRACING: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
4584 |     printf("TRACING: identical: the lengths are:\n[%i]\n[%i]\n", strlen(temp1), strlen(temp2));
4585 |   }
4586 |   free(arg1);
4587 |   free(arg2);
4588 |   free(temp1);
4589 |   free(temp2);
4590 |   if(result  == 0)
4591 |   {
4592 |     if(tracing) 
4593 | 	{
4594 |       printf("TRACING: identical returning 1\n");
4595 |     }
4596 |     return 1;
4597 |   }
4598 |   else
4599 |   {
4600 |     if(tracing) 
4601 | 	{
4602 |       printf("TRACING: identical returning 0\n");
4603 |     }
4604 |     return 0;
4605 |   }
4606 | }
4607 | 
4608 | 
4609 | /* constructs an initials string from a given name (for NIC hdl generation) */
4610 | char * find_initials(const char * person_role_name)
4611 | {
4612 |    char * temp, *pos;
4613 |    char * initials = NULL;
4614 |    int len, i;
4615 |    char ** vector;
4616 | 
4617 |    temp = strdup(person_role_name);
4618 |    if ((pos = index(temp, '#')) != NULL)
4619 |    { /* delete the EOL comment */
4620 |      pos[0] = '\0';
4621 |    }
4622 | 
4623 |    vector = g_strsplit(temp, " ", 0);
4624 |    for (i = 0; vector[i] != NULL && i < 4; i++)
4625 |    {
4626 |      if ( (strlen(vector[i]) > 0 ) && isalpha( (int)(vector[i][0]) ) )
4627 | 	 {
4628 |        if (initials == NULL)
4629 | 	   {
4630 |          initials = (char *)malloc(2);
4631 |          initials[0] = vector[i][0]; 
4632 | 		 initials[1] = '\0';
4633 |        }
4634 | 	   else
4635 | 	   {
4636 |          len = strlen(initials);
4637 |          initials = (char *)realloc(initials, len + 2 );
4638 |          initials[len] = vector[i][0];
4639 |          initials[len + 1] = '\0';
4640 |        }
4641 |      }
4642 |    }
4643 |    free(temp);
4644 |    g_strfreev(vector);
4645 |    return initials;
4646 | }
4647 | 
4648 | 
4649 | 
4650 | 
4651 | /*  Gets the letter combination to be used in the automatically
4652 |     generated NIc handle. It the letter combination is specified
4653 |     in the AUTO NIC handle, return that. If not, return NULL
4654 |     (in which case the initials of the name must be used) */
4655 | char * get_combination_from_autonic(const char * autonic)
4656 | {
4657 |   GString * temp;
4658 |   char * str = NULL;
4659 |   char * pos;
4660 | 
4661 |   temp = g_string_new(autonic);
4662 |   temp = g_string_up(temp);
4663 |   if ((pos = index(temp->str, '#')) != NULL)
4664 |   { 
4665 |     /* delete the EOL comment */
4666 |     pos[0] = '\0';
4667 |   }
4668 |   g_strstrip(temp->str);
4669 |   temp->len = strlen(temp->str);/* we directly played with temp->str, so adjust temp->len accordingly */
4670 |  
4671 |   temp = g_string_erase(temp, 0, strlen("AUTO-"));
4672 |   /* delete all digits from the beginning of the string */
4673 |   while (temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9'))
4674 |   {
4675 |     temp = g_string_erase(temp, 0, 1);
4676 |   }
4677 | 
4678 |   if (temp->len < 2 )
4679 |   {
4680 |     g_string_free(temp, TRUE);
4681 |     return NULL;
4682 |   }
4683 |   else
4684 |   {
4685 |     str = temp->str;
4686 |     g_string_free(temp, FALSE);
4687 |     g_strup(str);
4688 |     if(strlen(str) > 4)
4689 | 	{
4690 |       str[4] = '\0'; 
4691 |     }
4692 |     return str;
4693 |   }
4694 | }
4695 | 
4696 | 
4697 | 
4698 | 
4699 | /* Gets an object whose NIC hdl is an auto NIC handle and to be modified (to be sent to RIPupdate)
4700 |    and  modifies the nic-hdl: attribute.
4701 |    For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
4702 |    auto_nic is set to "AUTO-1"
4703 |    auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
4704 | rpsl_object_t * replace_AUTO_NIC_hdl(rpsl_object_t *object, char * auto_nic_hdl)
4705 | {
4706 |   GList *nichdl_item;
4707 |   rpsl_object_t *object2 = NULL;
4708 |   rpsl_attr_t *attr;
4709 |   GList *class_attr;
4710 |   char * person_role_name = NULL;
4711 |   char * initials = NULL;
4712 |   char *value, *new_value = NULL;
4713 |   const char *type;
4714 |   int pos;
4715 | 
4716 |   if (tracing)
4717 |   {                                
4718 |       printf("TRACING: replace_AUTO_NIC_hdl running\n");
4719 |   }
4720 | 
4721 |   nichdl_item = rpsl_object_get_attr(object, "nic-hdl"); /* list with one item only */
4722 | 
4723 |   value = rpsl_attr_get_clean_value((rpsl_attr_t *)(nichdl_item->data));
4724 |   g_strdown(value);
4725 |   if (tracing)
4726 |   {                                
4727 |       printf("TRACING: auto nic-hdl value is [%s]\n", value);
4728 |   }
4729 | 
4730 |   if (strstr(value, "auto-") != NULL)
4731 |   {
4732 |     /* this attribute must be replaced with a new attribute containing a nic-hdl */
4733 |     strcpy(auto_nic_hdl, value);
4734 |     pos = rpsl_attr_get_ofs((rpsl_attr_t *)(nichdl_item->data));
4735 | 
4736 | 	if (tracing)
4737 | 	{                                
4738 |     	printf("TRACING: pos [%d]\n", pos);
4739 | 	}
4740 | 
4741 |      /* if the letter combination is already specified, get it */
4742 |     initials = get_combination_from_autonic(auto_nic_hdl);
4743 |     /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
4744 |     if(initials == NULL)
4745 | 	{
4746 | 	  type = rpsl_object_get_class(object);
4747 | 	  class_attr = rpsl_object_get_attr(object, type);
4748 | 	  person_role_name = rpsl_attr_get_clean_value((rpsl_attr_t *)(class_attr->data));
4749 | 	  rpsl_attr_delete_list(class_attr);
4750 |       initials = find_initials(person_role_name);
4751 | 	  free(person_role_name);
4752 |     }
4753 | 	if (tracing)
4754 | 	{                                
4755 |     	printf("TRACING: initials [%s]\n", initials ? initials : "NULL");
4756 | 	}
4757 | 
4758 | 	object2 = rpsl_object_copy(object);
4759 |     new_value = (char *)malloc(strlen(initials) + strlen(current_source) + 3);
4760 | 	strcpy(new_value, initials);
4761 | 	strcat(new_value, "*-");
4762 | 	strcat(new_value, current_source);
4763 | 	if (tracing)
4764 | 	{                                
4765 |     	printf("TRACING: new_value [%s]\n", new_value);
4766 | 	}
4767 | 
4768 | 	/* now copy original attribute, replace value, remove old attr and add replacement */
4769 | 	attr = rpsl_attr_copy((rpsl_attr_t *)(nichdl_item->data));
4770 | 	rpsl_attr_replace_value(attr, new_value);
4771 | 	free(initials);
4772 | 	free(new_value);
4773 | 	free(value);
4774 | 
4775 | 	/* remove the attribute with the auto- */
4776 | 	rpsl_object_remove_attr(object2, pos, NULL);
4777 | 		
4778 | 	/* insert new attribute with nic-hdl */
4779 | 	rpsl_object_add_attr(object2, attr, pos, NULL);
4780 |   }
4781 |   rpsl_attr_delete_list(nichdl_item);
4782 |   
4783 |   return(object2);
4784 | }
4785 | 
4786 | 
4787 | 
4788 | 
4789 | /* replaces the refs to AUTO NIC hdls with the assigned one */
4790 | 
4791 | char * replace_refs_to_AUTO_NIC_hdl(rpsl_object_t *object, GHashTable * auto_nic_hash, char *arg)
4792 | {
4793 |   char * nic_hdl = NULL;
4794 |   char *name;
4795 |   char *value;
4796 |   char *return_str;
4797 |   char *tempstr;
4798 |   rpsl_attr_t *attr;
4799 |   const GList * attr_list = NULL;
4800 |   const GList * list_item = NULL;
4801 |   int pos;
4802 | 
4803 |   if(tracing)
4804 |   {
4805 |     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is running: arg:[%s]\n", arg ? arg : "NULL");
4806 |   }
4807 | 
4808 |   attr_list = rpsl_object_get_all_attr(object);
4809 |   
4810 | //  for (list_item = attr_list; list_item != NULL; list_item = g_list_next(list_item ))
4811 | //  {
4812 |   list_item = attr_list;
4813 |   while (list_item != NULL)
4814 |   {
4815 | 	name = strdup(rpsl_attr_get_name((rpsl_attr_t *)(list_item->data)));
4816 | 	g_strdown(name);
4817 | 	value = rpsl_attr_get_clean_value((rpsl_attr_t *)(list_item->data));
4818 | 	g_strdown(value);
4819 | 	pos = rpsl_attr_get_ofs((rpsl_attr_t *)(list_item->data));
4820 |   	if (    strstr(name, "admin-c") == name
4821 | 	     || strstr(name, "tech-c")  == name
4822 | 	     || strstr(name, "zone-c")  == name
4823 | 	     || strstr(name, "author")  == name )
4824 | 	{
4825 | 	  /* attr starts with admin-c, tech-c, zone-c or author */
4826 | 	  if ( strstr(value, "auto-") != NULL)
4827 | 	  {
4828 |         if(tracing)
4829 | 		{
4830 | 			printf("TRACING: replace_refs_to_AUTO_NIC_hdl: auto_nic is [%s]\n", value);
4831 |         }
4832 |         
4833 |         /* if we have this AUTO NIC hdl in the hash, put it in. */
4834 |         if( (nic_hdl = (char *)g_hash_table_lookup(auto_nic_hash, value)) )
4835 | 		{
4836 |         	if(tracing)
4837 | 			{
4838 | 				printf("TRACING: replace_refs_to_AUTO_NIC_hdl: nic_hdl is [%s]\n", nic_hdl);
4839 |         	}
4840 | 			/* create a new attribute with the auto nic handle */
4841 | 			attr = rpsl_attr_copy((rpsl_attr_t *)(list_item->data));
4842 |             rpsl_attr_replace_value(attr, nic_hdl);
4843 | 
4844 | 			/* remove the attribute with the auto- */
4845 | 			rpsl_object_remove_attr(object, pos, NULL);
4846 | 			
4847 | 			/* insert new attribute with nic-hdl */
4848 | 			rpsl_object_add_attr(object, attr, pos, NULL);
4849 | 
4850 |             /* replacing the attr destroys the list, so start the list again */
4851 |             attr_list = rpsl_object_get_all_attr(object);
4852 |             list_item = attr_list; 
4853 |         }
4854 | 		else
4855 | 		{ /* else, return 0 immediately */
4856 | 			free(name);
4857 | 			free (value);
4858 | 			return NULL;
4859 |         }
4860 | 	  }
4861 | 	}
4862 | 
4863 | 	free(name);
4864 | 	free (value);
4865 | 	
4866 | 	list_item = g_list_next(list_item);
4867 |   }
4868 | 	
4869 |   return_str =  rpsl_object_get_text(object,RPSL_STD_COLUMN);
4870 | 
4871 |   /* now, if we don't have a '\n' at the end of the return_str  string, we will
4872 |      add one, since RAToolSet parser cannot deal with objects without a '\n' at the end */
4873 |   if(return_str[strlen(return_str) - 1] != '\n')
4874 |   {
4875 |     /* so, add a '\n' */
4876 |     tempstr = (char *)malloc(strlen(return_str) + 2);
4877 |     sprintf(tempstr, "%s\n", return_str);
4878 |     free(return_str);
4879 |     return_str = tempstr;
4880 |   }
4881 |    
4882 |   if (tracing)
4883 |   {
4884 |     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is returning,\nreturn_str=[%s]\n", return_str);
4885 |   }
4886 | 
4887 |   return return_str;
4888 | }
4889 | 
4890 | 
4891 | 
4892 | 
4893 | /* UP_put_assigned_NIC will replace the auto NIC handle of the object with its
4894 |    assigned NIC handle and return an amended copy of the object */
4895 | rpsl_object_t * UP_put_assigned_NIC(rpsl_object_t *object, char * assigned_NIC)
4896 | {
4897 |   rpsl_object_t *object2;
4898 |   rpsl_attr_t *attr;
4899 |   GList * nichdl_item;
4900 |   char *value;
4901 |   int pos;
4902 | 
4903 |   nichdl_item = rpsl_object_get_attr(object, "nic-hdl");  /* a list with only one item */
4904 | 
4905 |   value = rpsl_attr_get_clean_value((rpsl_attr_t *)(nichdl_item->data));
4906 |   g_strdown(value);
4907 |   if (strstr(value, "auto-") != NULL)
4908 |   {
4909 |     /* replace the AUTO-NIC hdl with the assigned one  */
4910 | 
4911 |     if (tracing)
4912 |     {
4913 |       printf("TRACING: UP_put_assigned_NIC: auto_nic is [%s]\n", value);
4914 |     }
4915 | 
4916 | 	object2 = rpsl_object_copy(object);
4917 | 	/* now copy original attribute, replace value, remove old attr and add replacement */
4918 | 	attr = rpsl_attr_copy((rpsl_attr_t *)(nichdl_item->data));
4919 | 	rpsl_attr_replace_value(attr, assigned_NIC);
4920 |     pos = rpsl_attr_get_ofs((rpsl_attr_t *)(nichdl_item->data));
4921 | 
4922 | 	/* remove the attribute with the auto- */
4923 | 	rpsl_object_remove_attr(object2, pos, NULL);
4924 | 		
4925 | 	/* insert new attribute with nic-hdl */
4926 | 	rpsl_object_add_attr(object2, attr, pos, NULL);
4927 |   }
4928 |   rpsl_attr_delete_list(nichdl_item);
4929 | 
4930 |   return object2;
4931 | }
4932 | 
4933 | 
4934 | 
4935 | 
4936 | /* Takes a parsed object, and returns 1 if this object has 
4937 |    an AUTO NIC handle. Otherwise, returns 0 */
4938 | int has_AUTO_NIC_hdl(const rpsl_object_t * object)
4939 | {
4940 |   GList *attributes = NULL;
4941 | 
4942 |   if ( !rpsl_object_is_deleted(object) )
4943 |   {
4944 |     attributes = rpsl_object_get_attr(object, "nic-hdl");
4945 |     if (attributes != NULL)
4946 | 	{
4947 |       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
4948 | 	  { /* if it contains a ref to AUTO nic */
4949 |         rpsl_attr_delete_list(attributes);
4950 |         return 1;
4951 |       }
4952 |     }
4953 |     /* if control reaches here, then we will return 0 */
4954 |     rpsl_attr_delete_list(attributes);
4955 |     return 0; 
4956 |   }
4957 |   else
4958 |   { /* it doesn't pass syntax check. So, it doesn't matter if 
4959 |            it contains refs to AUTO NIC hdls. */
4960 |     return 0;        
4961 |   }
4962 | }
4963 | 
4964 | 
4965 | /* Takes an rpsl_object_t structure , and returns 1 if this object contains
4966 |    a reference to an AUTO NIC handle. Otherwise, returns 0 */
4967 | int has_ref_to_AUTO_nic_hdl(rpsl_object_t *object)
4968 | {
4969 |   GList * attributes = NULL;
4970 | 
4971 |   if (! rpsl_object_is_deleted(object) )
4972 |   {
4973 |     attributes = rpsl_object_get_attr(object, "admin-c");
4974 |     rpsl_attr_split_multiple(&attributes);
4975 |     if (attributes != NULL)
4976 | 	{
4977 |       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
4978 | 	  { /* if it contains a ref to AUTO nic */
4979 |         rpsl_attr_delete_list(attributes);
4980 |         return 1;
4981 |       }
4982 |     }
4983 |     rpsl_attr_delete_list(attributes);
4984 |     attributes = rpsl_object_get_attr(object, "tech-c");
4985 |     rpsl_attr_split_multiple(&attributes);
4986 |     if (attributes != NULL)
4987 | 	{
4988 |       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
4989 | 	  { /* if it contains a ref to AUTO nic */
4990 |         rpsl_attr_delete_list(attributes);
4991 |         return 1;
4992 |       }
4993 |     }
4994 | 
4995 |     rpsl_attr_delete_list(attributes);
4996 |     attributes = rpsl_object_get_attr(object, "zone-c");
4997 |     rpsl_attr_split_multiple(&attributes);
4998 |     if (attributes != NULL)
4999 | 	{
5000 |       if(strstr_in_attr_list(attributes, "AUTO-") == 1)
5001 | 	  { /* if it contains a ref to AUTO nic */
5002 |         rpsl_attr_delete_list(attributes);
5003 |         return 1;
5004 |       }
5005 |     }
5006 |     rpsl_attr_delete_list(attributes);
5007 |     attributes = rpsl_object_get_attr(object, "author");
5008 |     rpsl_attr_split_multiple(&attributes);
5009 |     if (attributes != NULL)
5010 | 	{
5011 |       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
5012 | 	  { /* if it contains a ref to AUTO nic */
5013 |         rpsl_attr_delete_list(attributes);
5014 |         return 1;
5015 |       }
5016 |     }
5017 |     rpsl_attr_delete_list(attributes);
5018 |     /* if control reaches here, then we will return 0 */
5019 |     return 0; 
5020 |   }
5021 |   else
5022 |   {  /* it doesn't pass syntax check. So, it doesn't matter if 
5023 |            it contains refs to AUTO NIC hdls. */
5024 |     return 0;        
5025 |   }
5026 | }
5027 | 
5028 | 
5029 | 
5030 | /* Gets the "From" line of the incoming mail message and finds out an 
5031 |    address to send the acknowledgement */
5032 | char * find_email_address(const char * from_line)
5033 | {
5034 |   char * pos1 = NULL, * pos2 = NULL, * pos = NULL;
5035 |   char * temp = NULL;
5036 |   char * part1 = NULL, * part2 = NULL;
5037 |   
5038 |   if (from_line == NULL)
5039 |   {
5040 |     return NULL;
5041 |   }
5042 |   if (strstr(from_line, "From:") != from_line)
5043 |   {
5044 |     temp = strdup(from_line);
5045 |   }
5046 |   else
5047 |   {
5048 |     temp = strdup(from_line + strlen("From:"));
5049 |   }
5050 |   g_strstrip(temp);
5051 |   if (index(temp, '<'))
5052 |   { /* then the line is something like '"John White" <john@inter.net>' */
5053 |     pos1 = index(temp, '<');
5054 |     pos2 = index(temp, '>');
5055 |     temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
5056 |     temp[pos2 - pos1 - 1] = '\0';
5057 |     if (tracing)
5058 | 	{
5059 |      printf("TRACING: find_email_address temp=[%s]\n", temp);
5060 |     }
5061 |   }
5062 | 
5063 |   /* and now, we have to remove the parts in parantheses */ 
5064 |   while (   index(temp, '(') != NULL && index(temp, ')') != NULL
5065 |           && index(temp, '(') < index(temp, ')') )
5066 |   {
5067 |     part1 = strdup(temp);
5068 |     /* terminate the string */
5069 |     pos = index(part1, '(');
5070 |     *pos = '\0';
5071 | 
5072 |     part2 = strdup(index(temp, ')') + 1);
5073 |     strcat(part1, part2);
5074 |     free(temp);
5075 |     temp = strdup(part1);
5076 |     free(part1);
5077 |     free(part2);
5078 |   }
5079 |   
5080 |   g_strstrip(temp); 
5081 |   return temp;
5082 | }  
5083 | 
5084 | 
5085 | 
5086 | /* removes the '\n's and '\r's at the end of the arg, and returns it  */
5087 | char * UP_remove_EOLs(char * arg)
5088 | {
5089 |   while ( strlen(arg) > 0 &&
5090 |           (arg[strlen(arg) - 1] == '\n' || 
5091 |            arg[strlen(arg) - 1] == '\r') )
5092 |   {
5093 |     arg[strlen(arg) - 1] = '\0';
5094 |   }
5095 |  
5096 |   return arg;
5097 | }
5098 | 
5099 | 
5100 | 
5101 | /* Duplicates the given arg, and replaces 
5102 |     $FROM,
5103 |     $SUBJECT,
5104 |     $MDATE,
5105 |     $MSGID,
5106 |     $CC,
5107 |     $HUMAILBOX
5108 |     $AUTOBOX
5109 |     $FROMHOST
5110 | 
5111 |     and $TIME & $DATE
5112 |     
5113 |     strings with the corresponding variables.
5114 |     
5115 | */
5116 | char * UP_replace_globals(const char * arg)
5117 | {
5118 |   GString * g_str;
5119 |   char * to_be_returned;
5120 |   time_t cur_time;
5121 |   char * temp, * time_str, * date_str;
5122 | 
5123 |   /* get time */
5124 |   cur_time = time(NULL);
5125 |   temp = strdup(ctime(&cur_time));
5126 |   /* temp is now something like "Fri Sep 13 00:00:00 1986\n\0", fields are const width */ 
5127 |   
5128 |   time_str = (char *)malloc(9);  
5129 |   time_str = strncpy(time_str, temp + 11, 8);
5130 |   time_str[8] = '\0';  
5131 |             
5132 |   date_str = (char *)malloc(16);
5133 |   date_str = strncpy(date_str, temp, 11);
5134 |   date_str[11] = '\0';
5135 |   date_str = strncat(date_str, temp + 20, 4);
5136 |   
5137 |    
5138 |   free(temp);
5139 |                                          
5140 |   g_str = g_string_new(arg);
5141 | 
5142 |   g_str = UP_replace_GStrings(g_str, "$FROMHOST", netupdclientIP); 
5143 | 
5144 |   g_str = UP_replace_GStrings(g_str, "$TIME", time_str);
5145 | 
5146 |   g_str = UP_replace_GStrings(g_str, "$DATE", date_str);
5147 | 
5148 |   g_str = UP_replace_GStrings(g_str, "$SUBJECT", update_mail_subject);
5149 | 
5150 |   g_str = UP_replace_GStrings(g_str, "$FROM", update_mail_sender);
5151 | 
5152 |   g_str = UP_replace_GStrings(g_str, "$MDATE", update_mail_date); 
5153 | 
5154 |   g_str = UP_replace_GStrings(g_str, "$MSGID", update_mail_ID);
5155 | 
5156 |   if (update_mail_cc == NULL)
5157 |     g_str = UP_replace_GStrings(g_str, "$CC", ""); 
5158 |   else
5159 |     g_str = UP_replace_GStrings(g_str, "$CC", update_mail_cc);
5160 |   
5161 |   g_str = UP_replace_GStrings(g_str, "$HUMAILBOX", humailbox);
5162 | 
5163 |   g_str = UP_replace_GStrings(g_str, "$AUTOBOX", autobox);
5164 | 
5165 |   g_str = UP_replace_GStrings(g_str, "$HEADERTYPE", header_type); 
5166 | 
5167 |   g_str = UP_replace_GStrings(g_str, "$TEXTTYPE", text_type); 
5168 | 
5169 |   free(time_str);
5170 |   free(date_str);
5171 | 
5172 |   to_be_returned = strdup(g_str->str); 
5173 |   g_string_free(g_str, 1); 
5174 |   return to_be_returned;
5175 | }
5176 | 
5177 | 
5178 | 
5179 | 
5180 | /* Adds the given file to the update log */
5181 | void UP_add_to_upd_log(const char * filename)
5182 | {
5183 |   time_t now;
5184 |   struct tm * tmstr;
5185 |   time_t cur_time;
5186 |   char * time_str;
5187 |   char datestr[10]; 
5188 |   char * updlogfile;
5189 |   FILE * infile, * log_file;
5190 |   char   buf[1024];
5191 | 
5192 | 
5193 |   if (( infile = fopen(filename, "r")) == NULL)
5194 |   {
5195 |     fprintf(stderr, "UP_add_to_upd_log: Can't open upd file, %s\n", filename);
5196 |     return;
5197 |   }
5198 |   
5199 |   /* We need to get the a date string to construct the updlog file name */
5200 |   time(&now);
5201 |   tmstr = localtime(&now);
5202 |   strftime(datestr, 10, "%Y%m%d", tmstr);
5203 | 
5204 |   /* now that we have the date string, we can construct updlog file name */
5205 |   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
5206 |   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
5207 |            "%s.%s", updlog, datestr);
5208 |   
5209 |  
5210 |   if (( log_file = fopen(updlogfile, "a")) == NULL)
5211 |   {
5212 |     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", updlogfile);
5213 | 	free(updlogfile);
5214 |     return;
5215 |   }
5216 |    
5217 |   /* get time */
5218 |   cur_time = time(NULL);
5219 |   time_str = strdup(ctime(&cur_time));
5220 |   /* cut the '\n' at the end */
5221 |   time_str[strlen(time_str) - 1] = '\0';
5222 | 
5223 |   if (reading_from_mail)
5224 |   {
5225 |     fprintf(log_file, ">>> time: %s MAIL UPDATE <<<\n\n", time_str);
5226 |   }
5227 |   else if (networkupdate)
5228 |   {
5229 |     fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE (%s) <<<\n\n", 
5230 |                       time_str, netupdclientIP ? netupdclientIP : "NULL");
5231 |   }
5232 |   else if (webupdate)
5233 |   {
5234 |     fprintf(log_file, ">>> time: %s WEB UPDATE (%s) <<<\n\n", 
5235 |                        time_str, netupdclientIP ? netupdclientIP : "NULL");
5236 |   }
5237 |   else
5238 |   {
5239 |     fprintf(log_file, ">>> time: %s UPDATE <<<\n\n", time_str);
5240 |   }
5241 | 
5242 |   free(time_str);
5243 |   while ( fgets(buf, 1023, infile) != NULL ) 
5244 |   {
5245 |     fprintf(log_file, "%s", buf);
5246 |   }
5247 |   free(updlogfile);
5248 | 
5249 |   fclose(infile);
5250 |   fclose(log_file);
5251 | }
5252 | 
5253 | 
5254 | 
5255 | /* Logs the object to the update log */
5256 | void UP_log_networkupdate(const char * object_str, const char * host)
5257 | {
5258 |   time_t now;
5259 |   struct tm * tmstr;
5260 |   time_t cur_time;
5261 |   char * time_str;
5262 |   char datestr[10]; 
5263 |   char * updlogfile;
5264 |   FILE * log_file;
5265 | 
5266 |   /* We need to get the a date string to construct the updlog file name */
5267 |   time(&now);
5268 |   tmstr = localtime(&now);
5269 |   strftime(datestr, 10, "%Y%m%d", tmstr);
5270 | 
5271 |   /* now that we have the date string, we can construct updlog file name */
5272 |   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
5273 |   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
5274 |            "%s.%s", updlog, datestr);
5275 |   
5276 |   if (( log_file = fopen(updlogfile, "a")) == NULL)
5277 |   {
5278 |     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", updlogfile);
5279 | 	free(updlogfile);
5280 |     return;
5281 |   }
5282 |   free(updlogfile);
5283 |    
5284 |   /* get time */
5285 |   cur_time = time(NULL);
5286 |   time_str = strdup(ctime(&cur_time));
5287 |   /* cut the '\n' at the end */
5288 |   time_str[strlen(time_str) - 1] = '\0';
5289 | 
5290 |   fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE (%s) <<<\n\n", time_str, host);
5291 | 
5292 |   free(time_str);
5293 | 
5294 |   fprintf(log_file, "%s\n", object_str);
5295 | 
5296 |   fclose(log_file);
5297 | }
5298 | 
5299 | 
5300 | 
5301 | 
5302 | /* Performs a preliminary check on a string: Tries to guess if the arg is an object or not.
5303 |    The criteria is: If we have a colon (":") in the first line of the string, then it is
5304 |    probably an object */
5305 | int UP_is_object(const char * arg)
5306 | {
5307 |    if (arg == NULL)
5308 |    {
5309 |      return 0; /* not an object */
5310 |    }
5311 | 
5312 |    if (index(arg ,'\n'))
5313 |    { /* does it consist of multiple lines? */
5314 |      if (index(arg ,':') != NULL  && (index(arg ,':') < index(arg ,'\n')))
5315 | 	 {
5316 |        return 1;
5317 |      }
5318 | 	 else
5319 | 	 { /* it doesn't have any ":" or, first ":" is not in the first line */
5320 |        return 0;
5321 |      }
5322 |    }
5323 |    else
5324 |    { /* it has a single line, possibly not an object */
5325 |      return 0;
5326 |    }
5327 | }
5328 | 
5329 | 
5330 | int UP_remove_override_attr( rpsl_object_t *object )
5331 | {
5332 |   rpsl_error_t return_error;
5333 |   rpsl_attr_t *removed_attr;
5334 | 
5335 |   return_error.code = (gint)NULL;
5336 |   removed_attr = rpsl_object_remove_attr_name(object,"override",&return_error);
5337 |   if ( (removed_attr == NULL) && return_error.level >= RPSL_ERRLVL_ERROR )
5338 |   {
5339 | 	 /* error returned */
5340 | 	 /* could be that there was no override attribute in this object */
5341 |      if ( return_error.code == RPSL_ERR_NOSUCHATTR )
5342 | 	   return 1;  /* This is OK, object has no override attribute */
5343 | 	 else
5344 | 	   /* there was an override attr in this object and it has not been removed */
5345 | 	   return 0;
5346 |   }
5347 |   else
5348 |     /* no errors, override attribute has been removed */
5349 | 	 return 1; 
5350 | }
5351 | 
5352 | 
5353 | /****************************************************************************************************/
5354 | 
5355 | /*******************  Redundant Functions ***********************************************************/
5356 | 
5357 | 
5358 | 
5359 | /* strips lines beginning with "override:" off  */
5360 | char * delete_override(char * arg){
5361 | 
5362 |     char ** temp = NULL;
5363 |     char * string = NULL;
5364 |     int i;
5365 | 
5366 |     if(arg == NULL){
5367 |        return NULL;
5368 |     }
5369 | 
5370 |     /* split the string into lines */
5371 |     temp = g_strsplit (arg, "\n", 0);
5372 | 
5373 |     for(i=0; temp[i] != NULL; i++){
5374 |       /* if the line begins with "override:", then do not copy it */
5375 |       if(strstr(temp[i], "override:") != temp[i]){
5376 |         if(string == NULL){
5377 |           string = strdup(temp[i]);
5378 |         }else{
5379 |           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
5380 |           string = strcat(string, "\n");
5381 |           string = strcat(string, temp[i]);
5382 |         }
5383 |       }
5384 |     }
5385 |     g_strfreev(temp);
5386 |     return string;
5387 | }
5388 | 
5389 | 
5390 | /* takes a pre-parsed object, and returns its type */
5391 | /* char * get_class_type(Object *arg){
5392 |     
5393 |     char * be_returned = NULL;
5394 |     if(arg == NULL) return NULL;
5395 |     be_returned = strdup(arg->type->getName());  
5396 |     return g_strstrip(be_returned);
5397 | }
5398 | */
5399 | 
5400 | 
5401 | 
5402 | 
5403 | 
5404 | 
5405 | 
5406 | /*************** still used in nt module **************/
5407 | /* strips lines beginning with "delete:" off  */
5408 | char * delete_delete_attrib(char * arg){
5409 | 
5410 |     char ** temp = NULL;
5411 |     char * string = NULL;
5412 |     int i;
5413 | 
5414 |     if(arg == NULL){
5415 |        return NULL;
5416 |     }
5417 | 
5418 |     /* split the string into lines */
5419 |     temp = g_strsplit (arg, "\n", 0);
5420 | 
5421 |     for(i=0; temp[i] != NULL; i++){
5422 |       /* if the line begins with "delete:", then do not copy it */
5423 |       if(strstr(temp[i], "delete:") != temp[i]){
5424 |         if(string == NULL){
5425 |           string = strdup(temp[i]);
5426 |         }else{
5427 |           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
5428 |           string = strcat(string, "\n");
5429 |           string = strcat(string, temp[i]);
5430 |         }
5431 |       }
5432 |     }
5433 |     g_strfreev(temp);
5434 |     return string;
5435 | }