new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / shared / file_op.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 /* Functions to handle operation with files
11  */
12
13 #include <errno.h>
14 #include <string.h>
15
16 #include "shared.h"
17
18 #ifndef WIN32
19 #include <libgen.h>
20 #else
21 #include <aclapi.h>
22 #endif
23
24 /* Vista product information */
25 #ifdef WIN32
26 #ifndef PRODUCT_UNLICENSED
27 #define PRODUCT_UNLICENSED 0xABCDABCD
28 #endif
29 #ifndef PRODUCT_UNLICENSED_C
30 #define PRODUCT_UNLICENSED_C "Product Unlicensed "
31 #endif
32
33 #ifndef PRODUCT_BUSINESS
34 #define PRODUCT_BUSINESS 0x00000006
35 #endif
36 #ifndef PRODUCT_BUSINESS_C
37 #define PRODUCT_BUSINESS_C "Business Edition "
38 #endif
39
40 #ifndef PRODUCT_BUSINESS_N
41 #define PRODUCT_BUSINESS_N 0x00000010
42 #endif
43 #ifndef PRODUCT_BUSINESS_N_C
44 #define PRODUCT_BUSINESS_N_C "Business Edition "
45 #endif
46
47 #ifndef PRODUCT_CLUSTER_SERVER
48 #define PRODUCT_CLUSTER_SERVER 0x00000012
49 #endif
50 #ifndef PRODUCT_CLUSTER_SERVER_C
51 #define PRODUCT_CLUSTER_SERVER_C "Cluster Server Edition "
52 #endif
53
54 #ifndef PRODUCT_DATACENTER_SERVER
55 #define PRODUCT_DATACENTER_SERVER 0x00000008
56 #endif
57 #ifndef PRODUCT_DATACENTER_SERVER_C
58 #define PRODUCT_DATACENTER_SERVER_C "Datacenter Edition (full) "
59 #endif
60
61 #ifndef PRODUCT_DATACENTER_SERVER_CORE
62 #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
63 #endif
64 #ifndef PRODUCT_DATACENTER_SERVER_CORE_C
65 #define PRODUCT_DATACENTER_SERVER_CORE_C "Datacenter Edition (core) "
66 #endif
67
68 #ifndef PRODUCT_DATACENTER_SERVER_CORE_V
69 #define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
70 #endif
71 #ifndef PRODUCT_DATACENTER_SERVER_CORE_V_C
72 #define PRODUCT_DATACENTER_SERVER_CORE_V_C "Datacenter Edition (core) "
73 #endif
74
75 #ifndef PRODUCT_DATACENTER_SERVER_V
76 #define PRODUCT_DATACENTER_SERVER_V 0x00000025
77 #endif
78 #ifndef PRODUCT_DATACENTER_SERVER_V_C
79 #define PRODUCT_DATACENTER_SERVER_V_C "Datacenter Edition (full) "
80 #endif
81
82 #ifndef PRODUCT_ENTERPRISE
83 #define PRODUCT_ENTERPRISE 0x00000004
84 #endif
85 #ifndef PRODUCT_ENTERPRISE_C
86 #define PRODUCT_ENTERPRISE_C "Enterprise Edition "
87 #endif
88
89 #ifndef PRODUCT_ENTERPRISE_N
90 #define PRODUCT_ENTERPRISE_N 0x0000001B
91 #endif
92 #ifndef PRODUCT_ENTERPRISE_N_C
93 #define PRODUCT_ENTERPRISE_N_C "Enterprise Edition "
94 #endif
95
96 #ifndef PRODUCT_ENTERPRISE_SERVER
97 #define PRODUCT_ENTERPRISE_SERVER 0x0000000A
98 #endif
99 #ifndef PRODUCT_ENTERPRISE_SERVER_C
100 #define PRODUCT_ENTERPRISE_SERVER_C "Enterprise Edition (full) "
101 #endif
102
103 #ifndef PRODUCT_ENTERPRISE_SERVER_CORE
104 #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
105 #endif
106 #ifndef PRODUCT_ENTERPRISE_SERVER_CORE_C
107 #define PRODUCT_ENTERPRISE_SERVER_CORE_C "Enterprise Edition (core) "
108 #endif
109
110 #ifndef PRODUCT_ENTERPRISE_SERVER_CORE_V
111 #define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
112 #endif
113 #ifndef PRODUCT_ENTERPRISE_SERVER_CORE_V_C
114 #define PRODUCT_ENTERPRISE_SERVER_CORE_V_C "Enterprise Edition (core) "
115 #endif
116
117 #ifndef PRODUCT_ENTERPRISE_SERVER_IA64
118 #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
119 #endif
120 #ifndef PRODUCT_ENTERPRISE_SERVER_IA64_C
121 #define PRODUCT_ENTERPRISE_SERVER_IA64_C "Enterprise Edition for Itanium-based Systems "
122 #endif
123
124 #ifndef PRODUCT_ENTERPRISE_SERVER_V
125 #define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
126 #endif
127 #ifndef PRODUCT_ENTERPRISE_SERVER_V_C
128 #define PRODUCT_ENTERPRISE_SERVER_V_C "Enterprise Edition (full) "
129 #endif
130
131 #ifndef PRODUCT_HOME_BASIC
132 #define PRODUCT_HOME_BASIC 0x00000002
133 #endif
134 #ifndef PRODUCT_HOME_BASIC_C
135 #define PRODUCT_HOME_BASIC_C "Home Basic Edition "
136 #endif
137
138 #ifndef PRODUCT_HOME_BASIC_N
139 #define PRODUCT_HOME_BASIC_N 0x00000005
140 #endif
141 #ifndef PRODUCT_HOME_BASIC_N_C
142 #define PRODUCT_HOME_BASIC_N_C "Home Basic Edition "
143 #endif
144
145 #ifndef PRODUCT_HOME_PREMIUM
146 #define PRODUCT_HOME_PREMIUM 0x00000003
147 #endif
148 #ifndef PRODUCT_HOME_PREMIUM_C
149 #define PRODUCT_HOME_PREMIUM_C "Home Premium Edition "
150 #endif
151
152 #ifndef PRODUCT_HOME_PREMIUM_N
153 #define PRODUCT_HOME_PREMIUM_N 0x0000001A
154 #endif
155 #ifndef PRODUCT_HOME_PREMIUM_N_C
156 #define PRODUCT_HOME_PREMIUM_N_C "Home Premium Edition "
157 #endif
158
159 #ifndef PRODUCT_HOME_SERVER
160 #define PRODUCT_HOME_SERVER 0x00000013
161 #endif
162 #ifndef PRODUCT_HOME_SERVER_C
163 #define PRODUCT_HOME_SERVER_C "Home Server Edition "
164 #endif
165
166 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT
167 #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
168 #endif
169 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C
170 #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C "Essential Business Server Management Server "
171 #endif
172
173 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING
174 #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
175 #endif
176 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C
177 #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C "Essential Business Server Messaging Server "
178 #endif
179
180 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY
181 #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
182 #endif
183 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C
184 #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C "Essential Business Server Security Server "
185 #endif
186
187 #ifndef PRODUCT_SERVER_FOR_SMALLBUSINESS
188 #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
189 #endif
190 #ifndef PRODUCT_SERVER_FOR_SMALLBUSINESS_C
191 #define PRODUCT_SERVER_FOR_SMALLBUSINESS_C "Small Business Edition "
192 #endif
193
194 #ifndef PRODUCT_SMALLBUSINESS_SERVER
195 #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
196 #endif
197 #ifndef PRODUCT_SMALLBUSINESS_SERVER_C
198 #define PRODUCT_SMALLBUSINESS_SERVER_C "Small Business Server "
199 #endif
200
201 #ifndef PRODUCT_SMALLBUSINESS_SERVER_PREMIUM
202 #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
203 #endif
204 #ifndef PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C
205 #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C "Small Business Server Premium Edition "
206 #endif
207
208 #ifndef PRODUCT_STANDARD_SERVER
209 #define PRODUCT_STANDARD_SERVER 0x00000007
210 #endif
211 #ifndef PRODUCT_STANDARD_SERVER_C
212 #define PRODUCT_STANDARD_SERVER_C "Standard Edition "
213 #endif
214
215 #ifndef PRODUCT_STANDARD_SERVER_CORE
216 #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
217 #endif
218 #ifndef PRODUCT_STANDARD_SERVER_CORE_C
219 #define PRODUCT_STANDARD_SERVER_CORE_C "Standard Edition (core) "
220 #endif
221
222 #ifndef PRODUCT_STANDARD_SERVER_CORE_V
223 #define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
224 #endif
225 #ifndef PRODUCT_STANDARD_SERVER_CORE_V_C
226 #define PRODUCT_STANDARD_SERVER_CORE_V_C "Standard Edition "
227 #endif
228
229 #ifndef PRODUCT_STANDARD_SERVER_V
230 #define PRODUCT_STANDARD_SERVER_V 0x00000024
231 #endif
232 #ifndef PRODUCT_STANDARD_SERVER_V_C
233 #define PRODUCT_STANDARD_SERVER_V_C "Standard Edition "
234 #endif
235
236 #ifndef PRODUCT_STARTER
237 #define PRODUCT_STARTER 0x0000000B
238 #endif
239 #ifndef PRODUCT_STARTER_C
240 #define PRODUCT_STARTER_C "Starter Edition "
241 #endif
242
243 #ifndef PRODUCT_STORAGE_ENTERPRISE_SERVER
244 #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
245 #endif
246 #ifndef PRODUCT_STORAGE_ENTERPRISE_SERVER_C
247 #define PRODUCT_STORAGE_ENTERPRISE_SERVER_C "Storage Server Enterprise Edition "
248 #endif
249
250 #ifndef PRODUCT_STORAGE_EXPRESS_SERVER
251 #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
252 #endif
253 #ifndef PRODUCT_STORAGE_EXPRESS_SERVER_C
254 #define PRODUCT_STORAGE_EXPRESS_SERVER_C "Storage Server Express Edition "
255 #endif
256
257 #ifndef PRODUCT_STORAGE_STANDARD_SERVER
258 #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
259 #endif
260 #ifndef PRODUCT_STORAGE_STANDARD_SERVER_C
261 #define PRODUCT_STORAGE_STANDARD_SERVER_C "Storage Server Standard Edition "
262 #endif
263
264 #ifndef PRODUCT_STORAGE_WORKGROUP_SERVER
265 #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
266 #endif
267 #ifndef PRODUCT_STORAGE_WORKGROUP_SERVER_C
268 #define PRODUCT_STORAGE_WORKGROUP_SERVER_C "Storage Server Workgroup Edition "
269 #endif
270
271 #ifndef PRODUCT_ULTIMATE
272 #define PRODUCT_ULTIMATE 0x00000001
273 #endif
274 #ifndef PRODUCT_ULTIMATE_C
275 #define PRODUCT_ULTIMATE_C "Ultimate Edition "
276 #endif
277
278 #ifndef PRODUCT_ULTIMATE_N
279 #define PRODUCT_ULTIMATE_N 0x0000001C
280 #endif
281 #ifndef PRODUCT_ULTIMATE_N_C
282 #define PRODUCT_ULTIMATE_N_C "Ultimate Edition "
283 #endif
284
285 #ifndef PRODUCT_WEB_SERVER
286 #define PRODUCT_WEB_SERVER 0x00000011
287 #endif
288 #ifndef PRODUCT_WEB_SERVER_C
289 #define PRODUCT_WEB_SERVER_C "Web Server Edition "
290 #endif
291
292 #ifndef PRODUCT_WEB_SERVER_CORE
293 #define PRODUCT_WEB_SERVER_CORE 0x0000001D
294 #endif
295 #ifndef PRODUCT_WEB_SERVER_CORE_C
296 #define PRODUCT_WEB_SERVER_CORE_C "Web Server Edition "
297 #endif
298 #endif /* WIN32 */
299
300 #ifdef WIN32
301 #define mkstemp(x) 0
302 #endif
303
304 const char *__local_name = "unset";
305
306 /* Set the name of the starting program */
307 void OS_SetName(const char *name)
308 {
309     __local_name = name;
310     return;
311 }
312
313 time_t File_DateofChange(const char *file)
314 {
315     struct stat file_status;
316
317     if (stat(file, &file_status) < 0) {
318         return (-1);
319     }
320
321     return (file_status.st_mtime);
322 }
323
324 int IsDir(const char *file)
325 {
326     struct stat file_status;
327     if (stat(file, &file_status) < 0) {
328         return (-1);
329     }
330     if (S_ISDIR(file_status.st_mode)) {
331         return (0);
332     }
333     return (-1);
334 }
335
336 int CreatePID(const char *name, int pid)
337 {
338     char file[256];
339     FILE *fp;
340
341     if (isChroot()) {
342         snprintf(file, 255, "%s/%s-%d.pid", OS_PIDFILE, name, pid);
343     } else {
344         snprintf(file, 255, "%s%s/%s-%d.pid", DEFAULTDIR,
345                  OS_PIDFILE, name, pid);
346     }
347
348     fp = fopen(file, "a");
349     if (!fp) {
350         return (-1);
351     }
352
353     fprintf(fp, "%d\n", pid);
354
355     if (chmod(file, 0640) != 0) {
356         fclose(fp);
357         return (-1);
358     }
359
360     fclose(fp);
361
362     return (0);
363 }
364
365 char *GetRandomNoise()
366 {
367     FILE *fp;
368     char buf[2048 + 1];
369     size_t frr = 0;
370
371     /* Reading urandom */
372     fp = fopen("/dev/urandom", "r");
373     if(!fp)
374     {
375         return(NULL);
376     }
377
378     buf[2048] = '\0';
379     frr = fread(buf, 1, 2048, fp);
380     if(frr == 0) {
381         merror("ERROR: GetRandomNoise() fread() returned 0.");
382         fclose(fp);
383         return(NULL);
384     }
385     buf[2048] = '\0';
386     fclose(fp);
387     return(strdup(buf));
388 }
389
390 int DeletePID(const char *name)
391 {
392     char file[256];
393
394     if (isChroot()) {
395         snprintf(file, 255, "%s/%s-%d.pid", OS_PIDFILE, name, (int)getpid());
396     } else {
397         snprintf(file, 255, "%s%s/%s-%d.pid", DEFAULTDIR,
398                  OS_PIDFILE, name, (int)getpid());
399     }
400
401     if (File_DateofChange(file) < 0) {
402         return (-1);
403     }
404
405     if (unlink(file)) {
406         log2file(
407             DELETE_ERROR,
408             __local_name,
409             file,
410             errno,
411             strerror(errno)
412         );
413     }
414
415     return (0);
416 }
417
418 int UnmergeFiles(const char *finalpath, const char *optdir)
419 {
420     int ret = 1;
421     size_t i = 0, n = 0, files_size = 0;
422     char *files;
423     char final_name[2048 + 1];
424     char buf[2048 + 1];
425     FILE *fp;
426     FILE *finalfp;
427
428     finalfp = fopen(finalpath, "r");
429     if (!finalfp) {
430         merror("%s: ERROR: Unable to read merged file: '%s'.",
431                __local_name, finalpath);
432         return (0);
433     }
434
435     while (1) {
436         /* Read header portion */
437         if (fgets(buf, sizeof(buf) - 1, finalfp) == NULL) {
438             break;
439         }
440
441         /* Initiator */
442         if (buf[0] != '!') {
443             continue;
444         }
445
446         /* Get file size and name */
447         files_size = (size_t) atol(buf + 1);
448
449         files = strchr(buf, '\n');
450         if (files) {
451             *files = '\0';
452         }
453
454         files = strchr(buf, ' ');
455         if (!files) {
456             ret = 0;
457             continue;
458         }
459         files++;
460
461         if (optdir) {
462             snprintf(final_name, 2048, "%s/%s", optdir, files);
463         } else {
464             strncpy(final_name, files, 2048);
465             final_name[2048] = '\0';
466         }
467
468         /* Open filename */
469         fp = fopen(final_name, "w");
470         if (!fp) {
471             ret = 0;
472             merror("%s: ERROR: Unable to unmerge file '%s': %s",
473                    __local_name, final_name, strerror(errno));
474         }
475
476         if (files_size < sizeof(buf) - 1) {
477             i = files_size;
478             files_size = 0;
479         } else {
480             i = sizeof(buf) - 1;
481             files_size -= sizeof(buf) - 1;
482         }
483
484         while ((n = fread(buf, 1, i, finalfp)) > 0) {
485             buf[n] = '\0';
486
487             if (fp) {
488                 fwrite(buf, n, 1, fp);
489             }
490
491             if (files_size == 0) {
492                 break;
493             } else {
494                 if (files_size < sizeof(buf) - 1) {
495                     i = files_size;
496                     files_size = 0;
497                 } else {
498                     i = sizeof(buf) - 1;
499                     files_size -= sizeof(buf) - 1;
500                 }
501             }
502         }
503
504         if (fp) {
505             fclose(fp);
506         }
507     }
508
509     fclose(finalfp);
510     return (ret);
511 }
512
513 int MergeAppendFile(const char *finalpath, const char *files)
514 {
515     size_t n = 0;
516     long files_size = 0;
517     char buf[2048 + 1];
518     const char *tmpfile;
519     FILE *fp;
520     FILE *finalfp;
521
522     /* Create a new entry */
523     if (files == NULL) {
524         finalfp = fopen(finalpath, "w");
525         if (!finalfp) {
526             merror("%s: ERROR: Unable to create merged file: '%s'.",
527                    __local_name, finalpath);
528             return (0);
529         }
530         fclose(finalfp);
531
532         return (1);
533     }
534
535     finalfp = fopen(finalpath, "a");
536     if (!finalfp) {
537         merror("%s: ERROR: Unable to append merged file: '%s'.",
538                __local_name, finalpath);
539         return (0);
540     }
541
542     fp = fopen(files, "r");
543     if (!fp) {
544         merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files);
545         fclose(finalfp);
546         return (0);
547     }
548
549     fseek(fp, 0, SEEK_END);
550     files_size = ftell(fp);
551
552     tmpfile = strrchr(files, '/');
553     if (tmpfile) {
554         tmpfile++;
555     } else {
556         tmpfile = files;
557     }
558     fprintf(finalfp, "!%ld %s\n", files_size, tmpfile);
559
560     fseek(fp, 0, SEEK_SET);
561
562     while ((n = fread(buf, 1, sizeof(buf) - 1, fp)) > 0) {
563         buf[n] = '\0';
564         fwrite(buf, n, 1, finalfp);
565     }
566
567     fclose(fp);
568
569     fclose(finalfp);
570     return (1);
571 }
572
573 int MergeFiles(const char *finalpath, char **files)
574 {
575     int i = 0, ret = 1;
576     size_t n = 0;
577     long files_size = 0;
578
579     char *tmpfile;
580     char buf[2048 + 1];
581     FILE *fp;
582     FILE *finalfp;
583
584     finalfp = fopen(finalpath, "w");
585     if (!finalfp) {
586         merror("%s: ERROR: Unable to create merged file: '%s'.",
587                __local_name, finalpath);
588         return (0);
589     }
590
591     while (files[i]) {
592         fp = fopen(files[i], "r");
593         if (!fp) {
594             merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files[i]);
595             i++;
596             ret = 0;
597             continue;
598         }
599
600         fseek(fp, 0, SEEK_END);
601         files_size = ftell(fp);
602
603         /* Remove last entry */
604         tmpfile = strrchr(files[i], '/');
605         if (tmpfile) {
606             tmpfile++;
607         } else {
608             tmpfile = files[i];
609         }
610
611         fprintf(finalfp, "!%ld %s\n", files_size, tmpfile);
612
613         fseek(fp, 0, SEEK_SET);
614         while ((n = fread(buf, 1, sizeof(buf) - 1, fp)) > 0) {
615             buf[n] = '\0';
616             fwrite(buf, n, 1, finalfp);
617         }
618
619         fclose(fp);
620         i++;
621     }
622
623     fclose(finalfp);
624     return (ret);
625 }
626
627
628 #ifndef WIN32
629 /* Get basename of path */
630 char *basename_ex(char *path)
631 {
632     return (basename(path));
633 }
634
635 /* Rename file or directory */
636 int rename_ex(const char *source, const char *destination)
637 {
638     if (rename(source, destination)) {
639         log2file(
640             RENAME_ERROR,
641             __local_name,
642             source,
643             destination,
644             errno,
645             strerror(errno)
646         );
647
648         return (-1);
649     }
650
651     return (0);
652 }
653
654 /* Create a temporary file */
655 int mkstemp_ex(char *tmp_path)
656 {
657     int fd;
658
659     fd = mkstemp(tmp_path);
660
661     if (fd == -1) {
662         log2file(
663             MKSTEMP_ERROR,
664             __local_name,
665             tmp_path,
666             errno,
667             strerror(errno)
668         );
669
670         return (-1);
671     }
672
673     /* mkstemp() only implicitly does this in POSIX 2008 */
674     if (fchmod(fd, 0600) == -1) {
675         close(fd);
676
677         log2file(
678             CHMOD_ERROR,
679             __local_name,
680             tmp_path,
681             errno,
682             strerror(errno)
683         );
684
685         if (unlink(tmp_path)) {
686             log2file(
687                 DELETE_ERROR,
688                 __local_name,
689                 tmp_path,
690                 errno,
691                 strerror(errno)
692             );
693         }
694
695         return (-1);
696     }
697
698     close(fd);
699     return (0);
700 }
701
702
703 /* Get uname. Memory must be freed after use */
704 char *getuname()
705 {
706     struct utsname uts_buf;
707
708     if (uname(&uts_buf) >= 0) {
709         char *ret;
710
711         ret = (char *) calloc(512, sizeof(char));
712         if (ret == NULL) {
713             return (NULL);
714         }
715
716         snprintf(ret, 511, "%s %s %s %s %s - %s %s",
717                  uts_buf.sysname,
718                  uts_buf.nodename,
719                  uts_buf.release,
720                  uts_buf.version,
721                  uts_buf.machine,
722                  __ossec_name, __version);
723
724         return (ret);
725     } else {
726         char *ret;
727         ret = (char *) calloc(512, sizeof(char));
728         if (ret == NULL) {
729             return (NULL);
730         }
731
732         snprintf(ret, 511, "No system info available -  %s %s",
733                  __ossec_name, __version);
734
735         return (ret);
736     }
737
738     return (NULL);
739 }
740
741 /* Daemonize a process without closing stdin/stdout/stderr */
742 void goDaemonLight()
743 {
744     pid_t pid;
745
746     pid = fork();
747
748     if (pid < 0) {
749         merror(FORK_ERROR, __local_name, errno, strerror(errno));
750         return;
751     } else if (pid) {
752         exit(0);
753     }
754
755     /* Become session leader */
756     if (setsid() < 0) {
757         merror(SETSID_ERROR, __local_name, errno, strerror(errno));
758         return;
759     }
760
761     /* Fork again */
762     pid = fork();
763     if (pid < 0) {
764         merror(FORK_ERROR, __local_name, errno, strerror(errno));
765         return;
766     } else if (pid) {
767         exit(0);
768     }
769
770     dup2(1, 2);
771
772     /* Go to / */
773     if (chdir("/") == -1) {
774         merror(CHDIR_ERROR, __local_name, "/", errno, strerror(errno));
775     }
776
777     return;
778 }
779
780 /* Daemonize a process */
781 void goDaemon()
782 {
783     int fd;
784     pid_t pid;
785
786     pid = fork();
787     if (pid < 0) {
788         merror(FORK_ERROR, __local_name, errno, strerror(errno));
789         return;
790     } else if (pid) {
791         exit(0);
792     }
793
794     /* Become session leader */
795     if (setsid() < 0) {
796         merror(SETSID_ERROR, __local_name, errno, strerror(errno));
797         return;
798     }
799
800     /* Fork again */
801     pid = fork();
802     if (pid < 0) {
803         merror(FORK_ERROR, __local_name, errno, strerror(errno));
804         return;
805     } else if (pid) {
806         exit(0);
807     }
808
809     /* Dup stdin, stdout and stderr to /dev/null */
810     if ((fd = open("/dev/null", O_RDWR)) >= 0) {
811         dup2(fd, 0);
812         dup2(fd, 1);
813         dup2(fd, 2);
814
815         close(fd);
816     }
817
818     /* Go to / */
819     if (chdir("/") == -1) {
820         merror(CHDIR_ERROR, __local_name, "/", errno, strerror(errno));
821     }
822
823     return;
824 }
825
826 #else /* WIN32 */
827
828 int checkVista()
829 {
830     char *m_uname;
831     isVista = 0;
832
833     m_uname = getuname();
834     if (!m_uname) {
835         merror(MEM_ERROR, __local_name, errno, strerror(errno));
836         return (0);
837     }
838
839     /* Check if the system is Vista (must be called during the startup) */
840     if (strstr(m_uname, "Windows Server 2008") ||
841             strstr(m_uname, "Vista") ||
842             strstr(m_uname, "Windows 7") ||
843             strstr(m_uname, "Windows 8") ||
844             strstr(m_uname, "Windows Server 2012")) {
845         isVista = 1;
846         verbose("%s: INFO: System is Vista or newer (%s).",
847                 __local_name, m_uname);
848     } else {
849         verbose("%s: INFO: System is older than Vista (%s).",
850                 __local_name, m_uname);
851     }
852
853     free(m_uname);
854
855     return (isVista);
856 }
857
858 /* Get basename of path */
859 char *basename_ex(char *path)
860 {
861     return (PathFindFileNameA(path));
862 }
863
864 /* Rename file or directory */
865 int rename_ex(const char *source, const char *destination)
866 {
867     if (!MoveFileEx(source, destination, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
868         log2file(
869             "%s: ERROR: Could not move (%s) to (%s) which returned (%lu)",
870             __local_name,
871             source,
872             destination,
873             GetLastError()
874         );
875
876         return (-1);
877     }
878
879     return (0);
880 }
881
882 /* Create a temporary file */
883 int mkstemp_ex(char *tmp_path)
884 {
885     DWORD dwResult;
886     int result;
887     int status = -1;
888
889     HANDLE h = NULL;
890     PACL pACL = NULL;
891     PSECURITY_DESCRIPTOR pSD = NULL;
892     EXPLICIT_ACCESS ea[2];
893     SECURITY_ATTRIBUTES sa;
894
895     PSID pAdminGroupSID = NULL;
896     PSID pSystemGroupSID = NULL;
897     SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};
898
899 #if defined(_MSC_VER) && _MSC_VER >= 1500
900     result = _mktemp_s(tmp_path, strlen(tmp_path) + 1);
901
902     if (result != 0) {
903         log2file(
904             "%s: ERROR: Could not create temporary file (%s) which returned (%d)",
905             __local_name,
906             tmp_path,
907             result
908         );
909
910         return (-1);
911     }
912 #else
913     if (_mktemp(tmp_path) == NULL) {
914         log2file(
915             "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]",
916             __local_name,
917             tmp_path,
918             errno,
919             strerror(errno)
920         );
921
922         return (-1);
923     }
924 #endif
925
926     /* Create SID for the BUILTIN\Administrators group */
927     result = AllocateAndInitializeSid(
928                  &SIDAuthNT,
929                  2,
930                  SECURITY_BUILTIN_DOMAIN_RID,
931                  DOMAIN_ALIAS_RID_ADMINS,
932                  0, 0, 0, 0, 0, 0,
933                  &pAdminGroupSID
934              );
935
936     if (!result) {
937         log2file(
938             "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)",
939             __local_name,
940             GetLastError()
941         );
942
943         goto cleanup;
944     }
945
946     /* Create SID for the SYSTEM group */
947     result = AllocateAndInitializeSid(
948                  &SIDAuthNT,
949                  1,
950                  SECURITY_LOCAL_SYSTEM_RID,
951                  0, 0, 0, 0, 0, 0, 0,
952                  &pSystemGroupSID
953              );
954
955     if (!result) {
956         log2file(
957             "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)",
958             __local_name,
959             GetLastError()
960         );
961
962         goto cleanup;
963     }
964
965     /* Initialize an EXPLICIT_ACCESS structure for an ACE */
966     ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
967
968     /* Add Administrators group */
969     ea[0].grfAccessPermissions = GENERIC_ALL;
970     ea[0].grfAccessMode = SET_ACCESS;
971     ea[0].grfInheritance = NO_INHERITANCE;
972     ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
973     ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
974     ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID;
975
976     /* Add SYSTEM group */
977     ea[1].grfAccessPermissions = GENERIC_ALL;
978     ea[1].grfAccessMode = SET_ACCESS;
979     ea[1].grfInheritance = NO_INHERITANCE;
980     ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
981     ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
982     ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID;
983
984     /* Set entries in ACL */
985     dwResult = SetEntriesInAcl(2, ea, NULL, &pACL);
986
987     if (dwResult != ERROR_SUCCESS) {
988         log2file(
989             "%s: ERROR: Could not set ACL entries which returned (%lu)",
990             __local_name,
991             dwResult
992         );
993
994         goto cleanup;
995     }
996
997     /* Initialize security descriptor */
998     pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(
999               LPTR,
1000               SECURITY_DESCRIPTOR_MIN_LENGTH
1001           );
1002
1003     if (pSD == NULL) {
1004         log2file(
1005             "%s: ERROR: Could not initialize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)",
1006             __local_name,
1007             GetLastError()
1008         );
1009
1010         goto cleanup;
1011     }
1012
1013     if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
1014         log2file(
1015             "%s: ERROR: Could not initialize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)",
1016             __local_name,
1017             GetLastError()
1018         );
1019
1020         goto cleanup;
1021     }
1022
1023     /* Set owner */
1024     if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) {
1025         log2file(
1026             "%s: ERROR: Could not set owner which returned (%lu)",
1027             __local_name,
1028             GetLastError()
1029         );
1030
1031         goto cleanup;
1032     }
1033
1034     /* Set group owner */
1035     if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) {
1036         log2file(
1037             "%s: ERROR: Could not set group owner which returned (%lu)",
1038             __local_name,
1039             GetLastError()
1040         );
1041
1042         goto cleanup;
1043     }
1044
1045     /* Add ACL to security descriptor */
1046     if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
1047         log2file(
1048             "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)",
1049             __local_name,
1050             GetLastError()
1051         );
1052
1053         goto cleanup;
1054     }
1055
1056     /* Initialize security attributes structure */
1057     sa.nLength = sizeof (SECURITY_ATTRIBUTES);
1058     sa.lpSecurityDescriptor = pSD;
1059     sa.bInheritHandle = FALSE;
1060
1061     h = CreateFileA(
1062             tmp_path,
1063             GENERIC_WRITE,
1064             0,
1065             &sa,
1066             CREATE_NEW,
1067             FILE_ATTRIBUTE_NORMAL,
1068             NULL
1069         );
1070
1071     if (h == INVALID_HANDLE_VALUE) {
1072         log2file(
1073             "%s: ERROR: Could not create temporary file (%s) which returned (%lu)",
1074             __local_name,
1075             tmp_path,
1076             GetLastError()
1077         );
1078
1079         goto cleanup;
1080     }
1081
1082     if (!CloseHandle(h)) {
1083         log2file(
1084             "%s: ERROR: Could not close file handle to (%s) which returned (%lu)",
1085             __local_name,
1086             tmp_path,
1087             GetLastError()
1088         );
1089
1090         goto cleanup;
1091     }
1092
1093     /* Success */
1094     status = 0;
1095
1096 cleanup:
1097     if (pAdminGroupSID) {
1098         FreeSid(pAdminGroupSID);
1099     }
1100
1101     if (pSystemGroupSID) {
1102         FreeSid(pSystemGroupSID);
1103     }
1104
1105     if (pACL) {
1106         LocalFree(pACL);
1107     }
1108
1109     if (pSD) {
1110         LocalFree(pSD);
1111     }
1112
1113     return (status);
1114 }
1115
1116 /* Get uname for Windows */
1117 char *getuname()
1118 {
1119     int ret_size = OS_SIZE_1024 - 2;
1120     char *ret = NULL;
1121     char os_v[128 + 1];
1122
1123     typedef void (WINAPI * PGNSI)(LPSYSTEM_INFO);
1124     typedef BOOL (WINAPI * PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
1125
1126     /* See http://msdn.microsoft.com/en-us/library/windows/desktop/ms724429%28v=vs.85%29.aspx */
1127     OSVERSIONINFOEX osvi;
1128     SYSTEM_INFO si;
1129     PGNSI pGNSI;
1130     PGPI pGPI;
1131     BOOL bOsVersionInfoEx;
1132     DWORD dwType;
1133
1134     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
1135     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1136
1137     if (!(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi))) {
1138         osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1139         if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
1140             return (NULL);
1141         }
1142     }
1143
1144     /* Allocate memory */
1145     os_calloc(OS_SIZE_1024 + 1, sizeof(char), ret);
1146     ret[OS_SIZE_1024] = '\0';
1147
1148     switch (osvi.dwPlatformId) {
1149         /* Test for the Windows NT product family */
1150         case VER_PLATFORM_WIN32_NT:
1151             if (osvi.dwMajorVersion == 6) {
1152                 if (osvi.dwMinorVersion == 0) {
1153                     if (osvi.wProductType == VER_NT_WORKSTATION ) {
1154                         strncat(ret, "Microsoft Windows Vista ", ret_size - 1);
1155                     } else {
1156                         strncat(ret, "Microsoft Windows Server 2008 ", ret_size - 1);
1157                     }
1158                 } else if (osvi.dwMinorVersion == 1) {
1159                     if (osvi.wProductType == VER_NT_WORKSTATION ) {
1160                         strncat(ret, "Microsoft Windows 7 ", ret_size - 1);
1161                     } else {
1162                         strncat(ret, "Microsoft Windows Server 2008 R2 ", ret_size - 1);
1163                     }
1164                 } else if (osvi.dwMinorVersion == 2) {
1165                     if (osvi.wProductType == VER_NT_WORKSTATION ) {
1166                         strncat(ret, "Microsoft Windows 8 ", ret_size - 1);
1167                     } else {
1168                         strncat(ret, "Microsoft Windows Server 2012 ", ret_size - 1);
1169                     }
1170                 } else if (osvi.dwMinorVersion == 3) {
1171                     if (osvi.wProductType == VER_NT_WORKSTATION ) {
1172                         strncat(ret, "Microsoft Windows 8.1 ", ret_size - 1);
1173                     } else {
1174                         strncat(ret, "Microsoft Windows Server 2012 R2 ", ret_size - 1);
1175                     }
1176                 }
1177
1178                 ret_size -= strlen(ret) + 1;
1179
1180
1181                 /* Get product version */
1182                 pGPI = (PGPI) GetProcAddress(
1183                            GetModuleHandle(TEXT("kernel32.dll")),
1184                            "GetProductInfo");
1185
1186                 pGPI( 6, 0, 0, 0, &dwType);
1187
1188                 switch (dwType) {
1189                     case PRODUCT_UNLICENSED:
1190                         strncat(ret, PRODUCT_UNLICENSED_C, ret_size - 1);
1191                         break;
1192                     case PRODUCT_BUSINESS:
1193                         strncat(ret, PRODUCT_BUSINESS_C, ret_size - 1);
1194                         break;
1195                     case PRODUCT_BUSINESS_N:
1196                         strncat(ret, PRODUCT_BUSINESS_N_C, ret_size - 1);
1197                         break;
1198                     case PRODUCT_CLUSTER_SERVER:
1199                         strncat(ret, PRODUCT_CLUSTER_SERVER_C, ret_size - 1);
1200                         break;
1201                     case PRODUCT_DATACENTER_SERVER:
1202                         strncat(ret, PRODUCT_DATACENTER_SERVER_C, ret_size - 1);
1203                         break;
1204                     case PRODUCT_DATACENTER_SERVER_CORE:
1205                         strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_C, ret_size - 1);
1206                         break;
1207                     case PRODUCT_DATACENTER_SERVER_CORE_V:
1208                         strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_V_C, ret_size - 1);
1209                         break;
1210                     case PRODUCT_DATACENTER_SERVER_V:
1211                         strncat(ret, PRODUCT_DATACENTER_SERVER_V_C, ret_size - 1);
1212                         break;
1213                     case PRODUCT_ENTERPRISE:
1214                         strncat(ret, PRODUCT_ENTERPRISE_C, ret_size - 1);
1215                         break;
1216                     case PRODUCT_ENTERPRISE_N:
1217                         strncat(ret, PRODUCT_ENTERPRISE_N_C, ret_size - 1);
1218                         break;
1219                     case PRODUCT_ENTERPRISE_SERVER:
1220                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_C, ret_size - 1);
1221                         break;
1222                     case PRODUCT_ENTERPRISE_SERVER_CORE:
1223                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_C, ret_size - 1);
1224                         break;
1225                     case PRODUCT_ENTERPRISE_SERVER_CORE_V:
1226                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_V_C, ret_size - 1);
1227                         break;
1228                     case PRODUCT_ENTERPRISE_SERVER_IA64:
1229                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_IA64_C, ret_size - 1);
1230                         break;
1231                     case PRODUCT_ENTERPRISE_SERVER_V:
1232                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_V_C, ret_size - 1);
1233                         break;
1234                     case PRODUCT_HOME_BASIC:
1235                         strncat(ret, PRODUCT_HOME_BASIC_C, ret_size - 1);
1236                         break;
1237                     case PRODUCT_HOME_BASIC_N:
1238                         strncat(ret, PRODUCT_HOME_BASIC_N_C, ret_size - 1);
1239                         break;
1240                     case PRODUCT_HOME_PREMIUM:
1241                         strncat(ret, PRODUCT_HOME_PREMIUM_C, ret_size - 1);
1242                         break;
1243                     case PRODUCT_HOME_PREMIUM_N:
1244                         strncat(ret, PRODUCT_HOME_PREMIUM_N_C, ret_size - 1);
1245                         break;
1246                     case PRODUCT_HOME_SERVER:
1247                         strncat(ret, PRODUCT_HOME_SERVER_C, ret_size - 1);
1248                         break;
1249                     case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
1250                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C, ret_size - 1);
1251                         break;
1252                     case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
1253                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C, ret_size - 1);
1254                         break;
1255                     case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
1256                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C, ret_size - 1);
1257                         break;
1258                     case PRODUCT_SERVER_FOR_SMALLBUSINESS:
1259                         strncat(ret, PRODUCT_SERVER_FOR_SMALLBUSINESS_C, ret_size - 1);
1260                         break;
1261                     case PRODUCT_SMALLBUSINESS_SERVER:
1262                         strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_C, ret_size - 1);
1263                         break;
1264                     case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
1265                         strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C, ret_size - 1);
1266                         break;
1267                     case PRODUCT_STANDARD_SERVER:
1268                         strncat(ret, PRODUCT_STANDARD_SERVER_C, ret_size - 1);
1269                         break;
1270                     case PRODUCT_STANDARD_SERVER_CORE:
1271                         strncat(ret, PRODUCT_STANDARD_SERVER_CORE_C, ret_size - 1);
1272                         break;
1273                     case PRODUCT_STANDARD_SERVER_CORE_V:
1274                         strncat(ret, PRODUCT_STANDARD_SERVER_CORE_V_C, ret_size - 1);
1275                         break;
1276                     case PRODUCT_STANDARD_SERVER_V:
1277                         strncat(ret, PRODUCT_STANDARD_SERVER_V_C, ret_size - 1);
1278                         break;
1279                     case PRODUCT_STARTER:
1280                         strncat(ret, PRODUCT_STARTER_C, ret_size - 1);
1281                         break;
1282                     case PRODUCT_STORAGE_ENTERPRISE_SERVER:
1283                         strncat(ret, PRODUCT_STORAGE_ENTERPRISE_SERVER_C, ret_size - 1);
1284                         break;
1285                     case PRODUCT_STORAGE_EXPRESS_SERVER:
1286                         strncat(ret, PRODUCT_STORAGE_EXPRESS_SERVER_C, ret_size - 1);
1287                         break;
1288                     case PRODUCT_STORAGE_STANDARD_SERVER:
1289                         strncat(ret, PRODUCT_STORAGE_STANDARD_SERVER_C, ret_size - 1);
1290                         break;
1291                     case PRODUCT_STORAGE_WORKGROUP_SERVER:
1292                         strncat(ret, PRODUCT_STORAGE_WORKGROUP_SERVER_C, ret_size - 1);
1293                         break;
1294                     case PRODUCT_ULTIMATE:
1295                         strncat(ret, PRODUCT_ULTIMATE_C, ret_size - 1);
1296                         break;
1297                     case PRODUCT_ULTIMATE_N:
1298                         strncat(ret, PRODUCT_ULTIMATE_N_C, ret_size - 1);
1299                         break;
1300                     case PRODUCT_WEB_SERVER:
1301                         strncat(ret, PRODUCT_WEB_SERVER_C, ret_size - 1);
1302                         break;
1303                     case PRODUCT_WEB_SERVER_CORE:
1304                         strncat(ret, PRODUCT_WEB_SERVER_CORE_C, ret_size - 1);
1305                         break;
1306                 }
1307
1308                 ret_size -= strlen(ret) + 1;
1309             } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
1310                 pGNSI = (PGNSI) GetProcAddress(
1311                             GetModuleHandle("kernel32.dll"),
1312                             "GetNativeSystemInfo");
1313                 if (NULL != pGNSI) {
1314                     pGNSI(&si);
1315                 }
1316
1317                 if ( GetSystemMetrics(89) )
1318                     strncat(ret, "Microsoft Windows Server 2003 R2 ",
1319                             ret_size - 1);
1320                 else if (osvi.wProductType == VER_NT_WORKSTATION &&
1321                          si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
1322                     strncat(ret,
1323                             "Microsoft Windows XP Professional x64 Edition ",
1324                             ret_size - 1 );
1325                 } else {
1326                     strncat(ret, "Microsoft Windows Server 2003, ", ret_size - 1);
1327                 }
1328
1329                 ret_size -= strlen(ret) + 1;
1330             } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
1331                 strncat(ret, "Microsoft Windows XP ", ret_size - 1);
1332
1333                 ret_size -= strlen(ret) + 1;
1334             } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) {
1335                 strncat(ret, "Microsoft Windows 2000 ", ret_size - 1);
1336
1337                 ret_size -= strlen(ret) + 1;
1338             } else if (osvi.dwMajorVersion <= 4) {
1339                 strncat(ret, "Microsoft Windows NT ", ret_size - 1);
1340
1341                 ret_size -= strlen(ret) + 1;
1342             } else {
1343                 strncat(ret, "Microsoft Windows Unknown ", ret_size - 1);
1344
1345                 ret_size -= strlen(ret) + 1;
1346             }
1347
1348             /* Test for specific product on Windows NT 4.0 SP6 and later */
1349             if (bOsVersionInfoEx) {
1350                 /* Test for the workstation type */
1351                 if (osvi.wProductType == VER_NT_WORKSTATION &&
1352                         si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64) {
1353                     if ( osvi.dwMajorVersion == 4 ) {
1354                         strncat(ret, "Workstation 4.0 ", ret_size - 1);
1355                     } else if ( osvi.wSuiteMask & VER_SUITE_PERSONAL ) {
1356                         strncat(ret, "Home Edition ", ret_size - 1);
1357                     } else {
1358                         strncat(ret, "Professional ", ret_size - 1);
1359                     }
1360
1361                     /* Fix size */
1362                     ret_size -= strlen(ret) + 1;
1363                 }
1364
1365                 /* Test for the server type */
1366                 else if ( osvi.wProductType == VER_NT_SERVER ||
1367                           osvi.wProductType == VER_NT_DOMAIN_CONTROLLER ) {
1368                     if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
1369                         if (si.wProcessorArchitecture ==
1370                                 PROCESSOR_ARCHITECTURE_IA64 ) {
1371                             if ( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1372                                 strncat(ret,
1373                                         "Datacenter Edition for Itanium-based Systems ",
1374                                         ret_size - 1);
1375                             else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1376                                 strncat(ret,
1377                                         "Enterprise Edition for Itanium-based Systems ",
1378                                         ret_size - 1);
1379
1380                             ret_size -= strlen(ret) + 1;
1381                         } else if ( si.wProcessorArchitecture ==
1382                                     PROCESSOR_ARCHITECTURE_AMD64 ) {
1383                             if ( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1384                                 strncat(ret, "Datacenter x64 Edition ",
1385                                         ret_size - 1 );
1386                             else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1387                                 strncat(ret, "Enterprise x64 Edition ",
1388                                         ret_size - 1 );
1389                             else
1390                                 strncat(ret, "Standard x64 Edition ",
1391                                         ret_size - 1 );
1392
1393                             ret_size -= strlen(ret) + 1;
1394                         } else {
1395                             if ( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1396                                 strncat(ret, "Datacenter Edition ",
1397                                         ret_size - 1 );
1398                             else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) {
1399                                 strncat(ret, "Enterprise Edition ", ret_size - 1);
1400                             } else if ( osvi.wSuiteMask == VER_SUITE_BLADE ) {
1401                                 strncat(ret, "Web Edition ", ret_size - 1 );
1402                             } else {
1403                                 strncat(ret, "Standard Edition ", ret_size - 1);
1404                             }
1405
1406                             ret_size -= strlen(ret) + 1;
1407                         }
1408                     } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) {
1409                         if ( osvi.wSuiteMask & VER_SUITE_DATACENTER ) {
1410                             strncat(ret, "Datacenter Server ", ret_size - 1);
1411                         } else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) {
1412                             strncat(ret, "Advanced Server ", ret_size - 1 );
1413                         } else {
1414                             strncat(ret, "Server ", ret_size - 1);
1415                         }
1416
1417                         ret_size -= strlen(ret) + 1;
1418                     } else if (osvi.dwMajorVersion <= 4) { /* Windows NT 4.0 */
1419                         if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1420                             strncat(ret, "Server 4.0, Enterprise Edition ",
1421                                     ret_size - 1 );
1422                         else {
1423                             strncat(ret, "Server 4.0 ", ret_size - 1);
1424                         }
1425
1426                         ret_size -= strlen(ret) + 1;
1427                     }
1428                 }
1429             }
1430             /* Test for specific product on Windows NT 4.0 SP5 and earlier */
1431             else {
1432                 HKEY hKey;
1433                 char szProductType[81];
1434                 DWORD dwBufLen = 80;
1435                 LONG lRet;
1436
1437                 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
1438                                      "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
1439                                      0, KEY_QUERY_VALUE, &hKey );
1440                 if (lRet == ERROR_SUCCESS) {
1441                     char __wv[32];
1442
1443                     lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL,
1444                                             (LPBYTE) szProductType, &dwBufLen);
1445                     RegCloseKey( hKey );
1446
1447                     if ((lRet == ERROR_SUCCESS) && (dwBufLen < 80) ) {
1448                         if (lstrcmpi( "WINNT", szProductType) == 0 ) {
1449                             strncat(ret, "Workstation ", ret_size - 1);
1450                         } else if (lstrcmpi( "LANMANNT", szProductType) == 0 ) {
1451                             strncat(ret, "Server ", ret_size - 1);
1452                         } else if (lstrcmpi( "SERVERNT", szProductType) == 0 ) {
1453                             strncat(ret, "Advanced Server " , ret_size - 1);
1454                         }
1455
1456                         ret_size -= strlen(ret) + 1;
1457
1458                         memset(__wv, '\0', 32);
1459                         snprintf(__wv, 31,
1460                                  "%d.%d ",
1461                                  (int)osvi.dwMajorVersion,
1462                                  (int)osvi.dwMinorVersion);
1463
1464                         strncat(ret, __wv, ret_size - 1);
1465                         ret_size -= strlen(__wv) + 1;
1466                     }
1467                 }
1468             }
1469
1470             /* Display service pack (if any) and build number */
1471             if ( osvi.dwMajorVersion == 4 &&
1472                     lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 ) {
1473                 HKEY hKey;
1474                 LONG lRet;
1475                 char __wp[64];
1476
1477                 memset(__wp, '\0', 64);
1478                 /* Test for SP6 versus SP6a */
1479                 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
1480                                      "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
1481                                      0, KEY_QUERY_VALUE, &hKey );
1482                 if ( lRet == ERROR_SUCCESS )
1483                     snprintf(__wp, 63, "Service Pack 6a (Build %d)",
1484                              (int)osvi.dwBuildNumber & 0xFFFF );
1485                 else { /* Windows NT 4.0 prior to SP6a */
1486                     snprintf(__wp, 63, "%s (Build %d)",
1487                              osvi.szCSDVersion,
1488                              (int)osvi.dwBuildNumber & 0xFFFF);
1489                 }
1490
1491                 strncat(ret, __wp, ret_size - 1);
1492                 ret_size -= strlen(__wp) + 1;
1493                 RegCloseKey( hKey );
1494             } else {
1495                 char __wp[64];
1496
1497                 memset(__wp, '\0', 64);
1498
1499                 snprintf(__wp, 63, "%s (Build %d)",
1500                          osvi.szCSDVersion,
1501                          (int)osvi.dwBuildNumber & 0xFFFF);
1502
1503                 strncat(ret, __wp, ret_size - 1);
1504                 ret_size -= strlen(__wp) + 1;
1505             }
1506             break;
1507
1508         /* Test for Windows Me/98/95 */
1509         case VER_PLATFORM_WIN32_WINDOWS:
1510             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) {
1511                 strncat(ret, "Microsoft Windows 95 ", ret_size - 1);
1512                 ret_size -= strlen(ret) + 1;
1513             }
1514
1515             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) {
1516                 strncat(ret, "Microsoft Windows 98 ", ret_size - 1);
1517                 ret_size -= strlen(ret) + 1;
1518             }
1519
1520             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) {
1521                 strncat(ret, "Microsoft Windows Millennium Edition",
1522                         ret_size - 1);
1523
1524                 ret_size -= strlen(ret) + 1;
1525             }
1526             break;
1527
1528         case VER_PLATFORM_WIN32s:
1529             strncat(ret, "Microsoft Win32s", ret_size - 1);
1530             ret_size -= strlen(ret) + 1;
1531             break;
1532     }
1533
1534     /* Add OSSEC-HIDS version */
1535     snprintf(os_v, 128, " - %s %s", __ossec_name, __version);
1536     strncat(ret, os_v, ret_size - 1);
1537
1538     return (ret);
1539
1540 }
1541
1542 #endif /* WIN32 */
1543
1544
1545 int w_ref_parent_folder(const char * path) {
1546     const char * str;
1547     char * ptr;
1548
1549     switch (path[0]) {
1550     case '\0':
1551         return 0;
1552
1553     case '.':
1554         switch (path[1]) {
1555         case '\0':
1556             return 0;
1557
1558         case '.':
1559             switch (path[2]) {
1560             case '\0':
1561                 return 1;
1562
1563             case '/':
1564 #ifdef WIN32
1565             case '\\':
1566 #endif
1567                 return 1;
1568             }
1569         }
1570     }
1571
1572 #ifdef WIN32
1573     for (str = path; ptr = strstr(str, "/.."), ptr || (ptr = strstr(str, "\\.."), ptr); str = ptr + 3) {
1574         if (ptr[3] == '\0' || ptr[3] == '/' || ptr[3] == '\\') {
1575 #else
1576     for (str = path; ptr = strstr(str, "/.."), ptr; str = ptr + 3) {
1577         if (ptr[3] == '\0' || ptr[3] == '/') {
1578 #endif
1579             return 1;
1580         }
1581     }
1582
1583     return 0;
1584 }