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