Remove references to malloc
[freeradius.git] / src / main / util.c
1 /*
2  * util.c       Various utility functions.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006  The FreeRADIUS server project
21  */
22
23 #include <freeradius-devel/ident.h>
24 RCSID("$Id$")
25
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/rad_assert.h>
28
29 #include <ctype.h>
30 #include <signal.h>
31
32 #include <sys/stat.h>
33 #include <fcntl.h>
34
35 /*
36  *      The signal() function in Solaris 2.5.1 sets SA_NODEFER in
37  *      sa_flags, which causes grief if signal() is called in the
38  *      handler before the cause of the signal has been cleared.
39  *      (Infinite recursion).
40  *
41  *      The same problem appears on HPUX, so we avoid it, if we can.
42  *
43  *      Using sigaction() to reset the signal handler fixes the problem,
44  *      so where available, we prefer that solution.
45  */
46
47 void (*reset_signal(int signo, void (*func)(int)))(int)
48 {
49 #ifdef HAVE_SIGACTION
50         struct sigaction act, oact;
51
52         memset(&act, 0, sizeof(act));
53         act.sa_handler = func;
54         sigemptyset(&act.sa_mask);
55         act.sa_flags = 0;
56 #ifdef  SA_INTERRUPT            /* SunOS */
57         act.sa_flags |= SA_INTERRUPT;
58 #endif
59         if (sigaction(signo, &act, &oact) < 0)
60                 return SIG_ERR;
61         return oact.sa_handler;
62 #else
63
64         /*
65          *      re-set by calling the 'signal' function, which
66          *      may cause infinite recursion and core dumps due to
67          *      stack growth.
68          *
69          *      However, the system is too dumb to implement sigaction(),
70          *      so we don't have a choice.
71          */
72         signal(signo, func);
73
74         return NULL;
75 #endif
76 }
77
78 /*
79  *      Per-request data, added by modules...
80  */
81 struct request_data_t {
82         request_data_t  *next;
83
84         void            *unique_ptr;
85         int             unique_int;
86         void            *opaque;
87         void            (*free_opaque)(void *);
88 };
89
90 /*
91  *      Add opaque data (with a "free" function) to a REQUEST.
92  *
93  *      The unique ptr is meant to be a module configuration,
94  *      and the unique integer allows the caller to have multiple
95  *      opaque data associated with a REQUEST.
96  */
97 int request_data_add(REQUEST *request,
98                      void *unique_ptr, int unique_int,
99                      void *opaque, void (*free_opaque)(void *))
100 {
101         request_data_t *this, **last, *next;
102
103         /*
104          *      Some simple sanity checks.
105          */
106         if (!request || !opaque) return -1;
107
108         this = next = NULL;
109         for (last = &(request->data); *last != NULL; last = &((*last)->next)) {
110                 if (((*last)->unique_ptr == unique_ptr) &&
111                     ((*last)->unique_int == unique_int)) {
112                         this = *last;
113
114                         next = this->next;
115
116                         if (this->opaque && /* free it, if necessary */
117                             this->free_opaque)
118                                 this->free_opaque(this->opaque);
119                         break;  /* replace the existing entry */
120                 }
121         }
122
123         if (!this) this = rad_malloc(sizeof(*this));
124         memset(this, 0, sizeof(*this));
125
126         this->next = next;
127         this->unique_ptr = unique_ptr;
128         this->unique_int = unique_int;
129         this->opaque = opaque;
130         this->free_opaque = free_opaque;
131
132         *last = this;
133
134         return 0;
135 }
136
137
138 /*
139  *      Get opaque data from a request.
140  */
141 void *request_data_get(REQUEST *request,
142                        void *unique_ptr, int unique_int)
143 {
144         request_data_t **last;
145
146         if (!request) return NULL;
147
148         for (last = &(request->data); *last != NULL; last = &((*last)->next)) {
149                 if (((*last)->unique_ptr == unique_ptr) &&
150                     ((*last)->unique_int == unique_int)) {
151                         request_data_t *this = *last;
152                         void *ptr = this->opaque;
153
154                         /*
155                          *      Remove the entry from the list, and free it.
156                          */
157                         *last = this->next;
158                         free(this);
159                         return ptr; /* don't free it, the caller does that */
160                 }
161         }
162
163         return NULL;            /* wasn't found, too bad... */
164 }
165
166
167 /*
168  *      Get opaque data from a request without removing it.
169  */
170 void *request_data_reference(REQUEST *request,
171                        void *unique_ptr, int unique_int)
172 {
173         request_data_t **last;
174
175         for (last = &(request->data); *last != NULL; last = &((*last)->next)) {
176                 if (((*last)->unique_ptr == unique_ptr) &&
177                     ((*last)->unique_int == unique_int)) {
178                         request_data_t *this = *last;
179                         void *ptr = this->opaque;
180
181                         return ptr;
182                 }
183         }
184
185         return NULL;            /* wasn't found, too bad... */
186 }
187
188
189 /*
190  *      Free a REQUEST struct.
191  */
192 void request_free(REQUEST **request_ptr)
193 {
194         REQUEST *request;
195
196         if (!request_ptr || !*request_ptr) {
197                 return;
198         }
199
200         request = *request_ptr;
201
202         rad_assert(!request->in_request_hash);
203 #ifdef WITH_PROXY
204         rad_assert(!request->in_proxy_hash);
205 #endif
206         rad_assert(!request->ev);
207
208         if (request->packet)
209                 rad_free(&request->packet);
210
211 #ifdef WITH_PROXY
212         if (request->proxy)
213                 rad_free(&request->proxy);
214 #endif
215
216         if (request->reply)
217                 rad_free(&request->reply);
218
219 #ifdef WITH_PROXY
220         if (request->proxy_reply)
221                 rad_free(&request->proxy_reply);
222 #endif
223
224         if (request->config_items)
225                 pairfree(&request->config_items);
226
227         request->username = NULL;
228         request->password = NULL;
229
230         if (request->data) {
231                 request_data_t *this, *next;
232
233                 for (this = request->data; this != NULL; this = next) {
234                         next = this->next;
235                         if (this->opaque && /* free it, if necessary */
236                             this->free_opaque)
237                                 this->free_opaque(this->opaque);
238                         free(this);
239                 }
240                 request->data = NULL;
241         }
242
243         if (request->root &&
244             (request->root->refcount > 0)) {
245                 request->root->refcount--;
246                 request->root = NULL;
247         }
248
249 #ifdef WITH_COA
250         if (request->coa) {
251                 request->coa->parent = NULL;
252                 rad_assert(request->coa->ev == NULL);
253                 request_free(&request->coa);
254         }
255
256         if (request->parent && (request->parent->coa == request)) {
257                 request->parent->coa = NULL;
258         }
259 #endif
260
261 #ifndef NDEBUG
262         request->magic = 0x01020304;    /* set the request to be nonsense */
263 #endif
264         request->client = NULL;
265 #ifdef WITH_PROXY
266         request->home_server = NULL;
267 #endif
268         talloc_free(request);
269         *request_ptr = NULL;
270 }
271
272 /*
273  *      Check a filename for sanity.
274  *
275  *      Allow only uppercase/lowercase letters, numbers, and '-_/.'
276  */
277 int rad_checkfilename(const char *filename)
278 {
279         if (strspn(filename, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_/.") == strlen(filename)) {
280                 return 0;
281         }
282
283         return -1;
284 }
285
286 /** Check if file exists
287  *
288  * @param filename to check.
289  * @return 0 if the file does not exist, 1 if the file exists, -1 if the file
290  *      exists but there was an error opening it. errno value should be usable
291  *      for error messages.
292  */
293 int rad_file_exists(const char *filename)
294 {
295         int des;
296         int ret = 1;
297         
298         if ((des = open(filename, O_RDONLY)) == -1) {
299                 if (errno == ENOENT) {
300                         ret = 0;
301                 } else {
302                         ret = -1;
303                 }
304         } else {
305                 close(des);
306         }
307         
308         return ret;
309 }
310
311 /*
312  *      Create possibly many directories.
313  *
314  *      Note that the input directory name is NOT a constant!
315  *      This is so that IF an error is returned, the 'directory' ptr
316  *      points to the name of the file which caused the error.
317  */
318 int rad_mkdir(char *directory, mode_t mode)
319 {
320         int rcode;
321         char *p;
322         struct stat st;
323
324         /*
325          *      If the directory exists, don't do anything.
326          */
327         if (stat(directory, &st) == 0) {
328                 return 0;
329         }
330
331         /*
332          *      Look for the LAST directory name.  Try to create that,
333          *      failing on any error.
334          */
335         p = strrchr(directory, FR_DIR_SEP);
336         if (p != NULL) {
337                 *p = '\0';
338                 rcode = rad_mkdir(directory, mode);
339
340                 /*
341                  *      On error, we leave the directory name as the
342                  *      one which caused the error.
343                  */
344                 if (rcode < 0) {
345                         if (errno == EEXIST) return 0;
346                         return rcode;
347                 }
348
349                 /*
350                  *      Reset the directory delimiter, and go ask
351                  *      the system to make the directory.
352                  */
353                 *p = FR_DIR_SEP;
354         } else {
355                 return 0;
356         }
357
358         /*
359          *      Having done everything successfully, we do the
360          *      system call to actually go create the directory.
361          */
362         rcode = mkdir(directory, mode & 0777);
363         if (rcode < 0) {
364                 return rcode;
365         }
366         
367         /*
368          *      Set things like sticky bits that aren't supported by
369          *      mkdir.
370          */
371         if (mode & ~0777) {
372                 rcode = chmod(directory, mode);
373         }
374         
375         return rcode;
376 }
377
378
379 /*
380  *      Allocate memory, or exit.
381  *
382  *      This call ALWAYS succeeds!
383  */
384 void *rad_malloc(size_t size)
385 {
386         void *ptr = malloc(size);
387
388         if (ptr == NULL) {
389                 radlog(L_ERR, "no memory");
390                 exit(1);
391         }
392
393         return ptr;
394 }
395
396
397 void *rad_calloc(size_t size)
398 {
399         void *ptr = rad_malloc(size);
400         memset(ptr, 0, size);
401         return ptr;
402 }
403
404 void rad_const_free(const void *ptr)
405 {
406         void *tmp;
407         if (!ptr) return;
408
409         memcpy(&tmp, &ptr, sizeof(tmp));
410         talloc_free(tmp);
411 }
412
413
414 /*
415  *      Signature for free is dumb, and raises errors when we try
416  *      to free const ptrs.
417  */
418 void rad_cfree(const void *ptr)
419 {
420         void *tmp;
421         if (!ptr) return;
422
423         memcpy(&tmp, &ptr, sizeof(tmp));
424         free(tmp);
425 }
426
427 /*
428  *      Logs an error message and aborts the program
429  *
430  */
431
432 void NEVER_RETURNS rad_assert_fail (const char *file, unsigned int line,
433                                     const char *expr)
434 {
435         radlog(L_ERR, "ASSERT FAILED %s[%u]: %s", file, line, expr);
436         abort();
437 }
438
439
440 /*
441  *      Create a new REQUEST data structure.
442  */
443 REQUEST *request_alloc(void)
444 {
445         REQUEST *request;
446
447         request = talloc_zero(NULL, REQUEST);
448 #ifndef NDEBUG
449         request->magic = REQUEST_MAGIC;
450 #endif
451 #ifdef WITH_PROXY
452         request->proxy = NULL;
453 #endif
454         request->reply = NULL;
455 #ifdef WITH_PROXY
456         request->proxy_reply = NULL;
457 #endif
458         request->config_items = NULL;
459         request->username = NULL;
460         request->password = NULL;
461         request->timestamp = time(NULL);
462         request->options = debug_flag; /* Default to global debug level */
463
464         request->module = "";
465         request->component = "<core>";
466         if (debug_flag) request->radlog = radlog_request;
467
468         return request;
469 }
470
471
472 /*
473  *      Create a new REQUEST, based on an old one.
474  *
475  *      This function allows modules to inject fake requests
476  *      into the server, for tunneled protocols like TTLS & PEAP.
477  */
478 REQUEST *request_alloc_fake(REQUEST *request)
479 {
480   REQUEST *fake;
481
482   fake = request_alloc();
483
484   fake->number = request->number;
485 #ifdef HAVE_PTHREAD_H
486   fake->child_pid = request->child_pid;
487 #endif
488   fake->parent = request;
489   fake->root = request->root;
490   fake->client = request->client;
491
492   /*
493    *    For new server support.
494    *
495    *    FIXME: Key instead off of a "virtual server" data structure.
496    *
497    *    FIXME: Permit different servers for inner && outer sessions?
498    */
499   fake->server = request->server;
500
501   fake->packet = rad_alloc(request, 1);
502   if (!fake->packet) {
503           request_free(&fake);
504           return NULL;
505   }
506
507   fake->reply = rad_alloc(request, 0);
508   if (!fake->reply) {
509           request_free(&fake);
510           return NULL;
511   }
512
513   fake->master_state = REQUEST_ACTIVE;
514   fake->child_state = REQUEST_RUNNING;
515
516   /*
517    *    Fill in the fake request.
518    */
519   fake->packet->sockfd = -1;
520   fake->packet->src_ipaddr = request->packet->src_ipaddr;
521   fake->packet->src_port = request->packet->src_port;
522   fake->packet->dst_ipaddr = request->packet->dst_ipaddr;
523   fake->packet->dst_port = 0;
524
525   /*
526    *    This isn't STRICTLY required, as the fake request MUST NEVER
527    *    be put into the request list.  However, it's still reasonable
528    *    practice.
529    */
530   fake->packet->id = fake->number & 0xff;
531   fake->packet->code = request->packet->code;
532   fake->timestamp = request->timestamp;
533
534   /*
535    *    Required for new identity support
536    */
537   fake->listener = request->listener;
538
539   /*
540    *    Fill in the fake reply, based on the fake request.
541    */
542   fake->reply->sockfd = fake->packet->sockfd;
543   fake->reply->src_ipaddr = fake->packet->dst_ipaddr;
544   fake->reply->src_port = fake->packet->dst_port;
545   fake->reply->dst_ipaddr = fake->packet->src_ipaddr;
546   fake->reply->dst_port = fake->packet->src_port;
547   fake->reply->id = fake->packet->id;
548   fake->reply->code = 0; /* UNKNOWN code */
549
550   /*
551    *    Copy debug information.
552    */
553   fake->options = request->options;
554   fake->radlog = request->radlog;
555
556   return fake;
557 }
558
559 #ifdef WITH_COA
560 REQUEST *request_alloc_coa(REQUEST *request)
561 {
562         if (!request || request->coa) return NULL;
563
564         /*
565          *      Originate CoA requests only when necessary.
566          */
567         if ((request->packet->code != PW_AUTHENTICATION_REQUEST) &&
568             (request->packet->code != PW_ACCOUNTING_REQUEST)) return NULL;
569
570         request->coa = request_alloc_fake(request);
571         if (!request->coa) return NULL;
572
573         request->coa->packet->code = 0; /* unknown, as of yet */
574         request->coa->child_state = REQUEST_RUNNING;
575         request->coa->proxy = rad_alloc(request->coa, 0);
576         if (!request->coa->proxy) {
577                 request_free(&request->coa);
578                 return NULL;
579         }
580
581         return request->coa;
582 }
583 #endif
584
585 /*
586  *      Copy a quoted string.
587  */
588 int rad_copy_string(char *to, const char *from)
589 {
590         int length = 0;
591         char quote = *from;
592
593         do {
594                 if (*from == '\\') {
595                         *(to++) = *(from++);
596                         length++;
597                 }
598                 *(to++) = *(from++);
599                 length++;
600         } while (*from && (*from != quote));
601
602         if (*from != quote) return -1; /* not properly quoted */
603
604         *(to++) = quote;
605         length++;
606         *to = '\0';
607
608         return length;
609 }
610
611 /*
612  *      Copy a quoted string but without the quotes. The length
613  *      returned is the number of chars written; the number of
614  *      characters consumed is 2 more than this.
615  */
616 int rad_copy_string_bare(char *to, const char *from)
617 {
618         int length = 0;
619         char quote = *from;
620
621         from++;
622         while (*from && (*from != quote)) {
623                 if (*from == '\\') {
624                         *(to++) = *(from++);
625                         length++;
626                 }
627                 *(to++) = *(from++);
628                 length++;
629         }
630
631         if (*from != quote) return -1; /* not properly quoted */
632
633         *to = '\0';
634
635         return length;
636 }
637
638
639 /*
640  *      Copy a %{} string.
641  */
642 int rad_copy_variable(char *to, const char *from)
643 {
644         int length = 0;
645         int sublen;
646
647         *(to++) = *(from++);
648         length++;
649
650         while (*from) {
651                 switch (*from) {
652                 case '"':
653                 case '\'':
654                         sublen = rad_copy_string(to, from);
655                         if (sublen < 0) return sublen;
656                         from += sublen;
657                         to += sublen;
658                         length += sublen;
659                         break;
660
661                 case '}':       /* end of variable expansion */
662                         *(to++) = *(from++);
663                         *to = '\0';
664                         length++;
665                         return length; /* proper end of variable */
666
667                 case '\\':
668                         *(to++) = *(from++);
669                         *(to++) = *(from++);
670                         length += 2;
671                         break;
672
673                 case '%':       /* start of variable expansion */
674                         if (from[1] == '{') {
675                                 *(to++) = *(from++);
676                                 length++;
677
678                                 sublen = rad_copy_variable(to, from);
679                                 if (sublen < 0) return sublen;
680                                 from += sublen;
681                                 to += sublen;
682                                 length += sublen;
683                                 break;
684                         } /* else FIXME: catch %%{ ?*/
685
686                         /* FALL-THROUGH */
687                 default:
688                         *(to++) = *(from++);
689                         length++;
690                         break;
691                 }
692         } /* loop over the input string */
693
694         /*
695          *      We ended the string before a trailing '}'
696          */
697
698         return -1;
699 }
700
701 #ifndef USEC
702 #define USEC 1000000
703 #endif
704
705 int rad_pps(int *past, int *present, time_t *then, struct timeval *now)
706 {
707         int pps;
708
709         if (*then != now->tv_sec) {
710                 *then = now->tv_sec;
711                 *past = *present;
712                 *present = 0;
713         }
714
715         /*
716          *      Bootstrap PPS by looking at a percentage of
717          *      the previous PPS.  This lets us take a moving
718          *      count, without doing a moving average.  If
719          *      we're a fraction "f" (0..1) into the current
720          *      second, we can get a good guess for PPS by
721          *      doing:
722          *
723          *      PPS = pps_now + pps_old * (1 - f)
724          *
725          *      It's an instantaneous measurement, rather than
726          *      a moving average.  This will hopefully let it
727          *      respond better to sudden spikes.
728          *
729          *      Doing the calculations by thousands allows us
730          *      to not overflow 2^32, AND to not underflow
731          *      when we divide by USEC.
732          */
733         pps = USEC - now->tv_usec; /* useconds left in previous second */
734         pps /= 1000;               /* scale to milliseconds */
735         pps *= *past;              /* multiply by past count to get fraction */
736         pps /= 1000;               /* scale to usec again */
737         pps += *present;           /* add in current count */
738
739         return pps;
740 }
741
742 /*
743  * Split a string into words, xlat each one and write into argv array.
744  * Return argc or -1 on failure.
745  */
746
747 int rad_expand_xlat(REQUEST *request, const char *cmd,
748                     int max_argc, const char *argv[], int can_fail,
749                     size_t argv_buflen, char *argv_buf)
750 {
751         const char *from;
752         char *to;
753         int argc = -1;
754         int i;
755         int left;
756
757         if (strlen(cmd) > (argv_buflen - 1)) {
758                 radlog(L_ERR, "rad_expand_xlat: Command line is too long");
759                 return -1;
760         }
761
762         /*
763          *      Check for bad escapes.
764          */
765         if (cmd[strlen(cmd) - 1] == '\\') {
766                 radlog(L_ERR, "rad_expand_xlat: Command line has final backslash, without a following character");
767                 return -1;
768         }
769
770         strlcpy(argv_buf, cmd, argv_buflen);
771
772         /*
773          *      Split the string into argv's BEFORE doing radius_xlat...
774          */
775         from = cmd;
776         to = argv_buf;
777         argc = 0;
778         while (*from) {
779                 int length;
780
781                 /*
782                  *      Skip spaces.
783                  */
784                 if ((*from == ' ') || (*from == '\t')) {
785                         from++;
786                         continue;
787                 }
788
789                 argv[argc] = to;
790                 argc++;
791
792                 if (argc >= (max_argc - 1)) break;
793
794                 /*
795                  *      Copy the argv over to our buffer.
796                  */
797                 while (*from && (*from != ' ') && (*from != '\t')) {
798                         if (to >= argv_buf + argv_buflen - 1) {
799                                 radlog(L_ERR, "rad_expand_xlat: Ran out of space in command line");
800                                 return -1;
801                         }
802
803                         switch (*from) {
804                         case '"':
805                         case '\'':
806                                 length = rad_copy_string_bare(to, from);
807                                 if (length < 0) {
808                                         radlog(L_ERR, "rad_expand_xlat: Invalid string passed as argument");
809                                         return -1;
810                                 }
811                                 from += length+2;
812                                 to += length;
813                                 break;
814
815                         case '%':
816                                 if (from[1] == '{') {
817                                         *(to++) = *(from++);
818
819                                         length = rad_copy_variable(to, from);
820                                         if (length < 0) {
821                                                 radlog(L_ERR, "rad_expand_xlat: Invalid variable expansion passed as argument");
822                                                 return -1;
823                                         }
824                                         from += length;
825                                         to += length;
826                                 } else { /* FIXME: catch %%{ ? */
827                                         *(to++) = *(from++);
828                                 }
829                                 break;
830
831                         case '\\':
832                                 if (from[1] == ' ') from++;
833                                 /* FALL-THROUGH */
834
835                         default:
836                                 *(to++) = *(from++);
837                         }
838                 } /* end of string, or found a space */
839
840                 *(to++) = '\0'; /* terminate the string */
841         }
842
843         /*
844          *      We have to have SOMETHING, at least.
845          */
846         if (argc <= 0) {
847                 radlog(L_ERR, "rad_expand_xlat: Empty command line.");
848                 return -1;
849         }
850
851         /*
852          *      Expand each string, as appropriate.
853          */
854         left = argv_buf + argv_buflen - to;
855         for (i = 0; i < argc; i++) {
856                 int sublen;
857
858                 /*
859                  *      Don't touch argv's which won't be translated.
860                  */
861                 if (strchr(argv[i], '%') == NULL) continue;
862
863                 if (!request) continue;
864
865                 sublen = radius_xlat(to, left - 1, argv[i], request, NULL, NULL);
866                 if (sublen <= 0) {
867                         if (can_fail) {
868                                 /*
869                                  *      Fail to be backwards compatible.
870                                  *
871                                  *      It's yucky, but it won't break anything,
872                                  *      and it won't cause security problems.
873                                  */
874                                 sublen = 0;
875                         } else {
876                                 radlog(L_ERR, "rad_expand_xlat: xlat failed");
877                                 return -1;
878                         }
879                 }
880
881                 argv[i] = to;
882                 to += sublen;
883                 *(to++) = '\0';
884                 left -= sublen;
885                 left--;
886
887                 if (left <= 0) {
888                         radlog(L_ERR, "rad_expand_xlat: Ran out of space while expanding arguments.");
889                         return -1;
890                 }
891         }
892         argv[argc] = NULL;
893
894         return argc;
895 }
896