d7860a12c4b52c386190a8a33635f3fcf7127983
[ossec-hids.git] / src / shared / file_op.c
1 /* @(#) $Id: ./src/shared/file_op.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All rights reserved.
6  *
7  * This program is a free software; you can redistribute it
8  * and/or modify it under the terms of the GNU General Public
9  * License (version 2) as published by the FSF - Free Software
10  * Foundation
11  */
12
13
14 /* Functions to handle operation with files
15  */
16
17
18 #include "shared.h"
19
20 #ifndef WIN32
21 #include <libgen.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 #include <accctrl.h>
302 #include <aclapi.h>
303 #include <shlwapi.h>
304 #endif
305
306
307 /* Sets the name of the starting program */
308 void OS_SetName(char *name)
309 {
310     __local_name = name;
311     return;
312 }
313
314
315 int File_DateofChange(char *file)
316 {
317     struct stat file_status;
318
319     if(stat(file, &file_status) < 0)
320         return(-1);
321
322     return (file_status.st_mtime);
323 }
324
325 int IsDir(char *file)
326 {
327     struct stat file_status;
328     if(stat(file,&file_status) < 0)
329         return(-1);
330     if(S_ISDIR(file_status.st_mode))
331         return(0);
332     return(-1);
333 }
334
335
336 int CreatePID(char *name, int pid)
337 {
338     char file[256];
339     FILE *fp;
340
341     if(isChroot())
342     {
343         snprintf(file,255,"%s/%s-%d.pid",OS_PIDFILE,name,pid);
344     }
345     else
346     {
347         snprintf(file,255,"%s%s/%s-%d.pid",DEFAULTDIR,
348                 OS_PIDFILE,name,pid);
349     }
350
351     fp = fopen(file,"a");
352     if(!fp)
353         return(-1);
354
355     fprintf(fp,"%d\n",pid);
356
357     chmod(file, 0640);
358
359     fclose(fp);
360
361     return(0);
362 }
363
364 int DeletePID(char *name)
365 {
366     char file[256];
367
368     if(isChroot())
369     {
370         snprintf(file,255,"%s/%s-%d.pid",OS_PIDFILE,name,(int)getpid());
371     }
372     else
373     {
374         snprintf(file,255,"%s%s/%s-%d.pid",DEFAULTDIR,
375                 OS_PIDFILE,name,(int)getpid());
376     }
377
378     if(File_DateofChange(file) < 0)
379         return(-1);
380
381     unlink(file);
382
383     return(0);
384 }
385
386
387 int UnmergeFiles(char *finalpath, char *optdir)
388 {
389     int i = 0, n = 0, ret = 1;
390     long files_size = 0;
391
392     char *files;
393     char final_name[2048 +1];
394     char buf[2048 + 1];
395     FILE *fp;
396     FILE *finalfp;
397
398     finalfp = fopen(finalpath, "r");
399     if(!finalfp)
400     {
401         merror("%s: ERROR: Unable to read merged file: '%s'.",
402                 __local_name, finalpath);
403         return(0);
404     }
405
406     while(1)
407     {
408         /* Reading header portion. */
409         if(fgets(buf, sizeof(buf) -1, finalfp) == NULL)
410         {
411             break;
412         }
413
414
415         /* Initiator. */
416         if(buf[0] != '!')
417             continue;
418
419
420         /* Getting file size and name. */
421         files_size = atol(buf +1);
422
423         files = strchr(buf, '\n');
424         if(files)
425             *files = '\0';
426
427         files = strchr(buf, ' ');
428         if(!files)
429         {
430             ret = 0;
431             continue;
432         }
433         files++;
434
435
436         if(optdir)
437         {
438             snprintf(final_name, 2048, "%s/%s", optdir, files);
439         }
440         else
441         {
442             strncpy(final_name, files, 2048);
443             final_name[2048] = '\0';
444         }
445
446
447         /* Opening file name. */
448         fp = fopen(final_name,"w");
449         if(!fp)
450         {
451             ret = 0;
452             merror("%s: ERROR: Unable to unmerge file '%s'.",
453                     __local_name, final_name);
454         }
455
456
457         if(files_size < sizeof(buf) -1)
458         {
459             i = files_size;
460             files_size = 0;
461         }
462         else
463         {
464             i = sizeof(buf) -1;
465             files_size -= sizeof(buf) -1;
466         }
467
468         while((n = fread(buf, 1, i, finalfp)) > 0)
469         {
470             buf[n] = '\0';
471
472             if(fp)
473             {
474                 fwrite(buf, n, 1, fp);
475             }
476
477             if(files_size == 0)
478             {
479                 break;
480             }
481             else
482             {
483                 if(files_size < sizeof(buf) -1)
484                 {
485                     i = files_size;
486                     files_size = 0;
487                 }
488                 else
489                 {
490                     i = sizeof(buf) -1;
491                     files_size -= sizeof(buf) -1;
492                 }
493             }
494         }
495
496         if(fp)
497             fclose(fp);
498     }
499
500     fclose(finalfp);
501     return(ret);
502 }
503
504
505 int MergeAppendFile(char *finalpath, char *files)
506 {
507     int n = 0;
508     long files_size = 0;
509
510     char buf[2048 + 1];
511     char *tmpfile;
512     FILE *fp;
513     FILE *finalfp;
514
515
516     /* Creating a new entry. */
517     if(files == NULL)
518     {
519         finalfp = fopen(finalpath, "w");
520         if(!finalfp)
521         {
522             merror("%s: ERROR: Unable to create merged file: '%s'.",
523                     __local_name, finalpath);
524             return(0);
525         }
526         fclose(finalfp);
527
528         return(1);
529     }
530
531
532     finalfp = fopen(finalpath, "a");
533     if(!finalfp)
534     {
535         merror("%s: ERROR: Unable to append merged file: '%s'.",
536                 __local_name, finalpath);
537         return(0);
538     }
539
540
541     fp = fopen(files,"r");
542     if(!fp)
543     {
544         merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files);
545         fclose(finalfp);
546         return(0);
547     }
548
549
550     fseek(fp, 0, SEEK_END);
551     files_size = ftell(fp);
552
553     tmpfile = strrchr(files, '/');
554     if(tmpfile)
555     {
556         tmpfile++;
557     }
558     else
559     {
560         tmpfile = files;
561     }
562     fprintf(finalfp, "!%ld %s\n", files_size, tmpfile);
563
564     fseek(fp, 0, SEEK_SET);
565
566     while((n = fread(buf, 1, sizeof(buf) -1, fp)) > 0)
567     {
568         buf[n] = '\0';
569         fwrite(buf, n, 1, finalfp);
570     }
571
572     fclose(fp);
573
574     fclose(finalfp);
575     return(1);
576 }
577
578
579
580 int MergeFiles(char *finalpath, char **files)
581 {
582     int i = 0, n = 0, ret = 1;
583     long files_size = 0;
584
585     char *tmpfile;
586     char buf[2048 + 1];
587     FILE *fp;
588     FILE *finalfp;
589
590     finalfp = fopen(finalpath, "w");
591     if(!finalfp)
592     {
593         merror("%s: ERROR: Unable to create merged file: '%s'.",
594                __local_name, finalpath);
595         return(0);
596     }
597
598     while(files[i])
599     {
600         fp = fopen(files[i],"r");
601         if(!fp)
602         {
603             merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files[i]);
604             i++;
605             ret = 0;
606             continue;
607         }
608
609         fseek(fp, 0, SEEK_END);
610         files_size = ftell(fp);
611
612         /* Removing last entry. */
613         tmpfile = strrchr(files[i], '/');
614         if(tmpfile)
615         {
616             tmpfile++;
617         }
618         else
619         {
620             tmpfile = files[i];
621         }
622
623         fprintf(finalfp, "!%ld %s\n", files_size, tmpfile);
624
625         fseek(fp, 0, SEEK_SET);
626
627         while((n = fread(buf, 1, sizeof(buf) -1, fp)) > 0)
628         {
629             buf[n] = '\0';
630             fwrite(buf, n, 1, finalfp);
631         }
632
633         fclose(fp);
634         i++;
635     }
636
637     fclose(finalfp);
638     return(ret);
639 }
640
641
642 #ifndef WIN32
643 /* Get basename of path */
644 char *basename_ex(char *path)
645 {
646     return (basename(path));
647 }
648
649 /* Rename file or directory */
650 int rename_ex(const char *source, const char *destination)
651 {
652     if (rename(source, destination)) {
653         log2file(
654             RENAME_ERROR,
655             __local_name,
656             source,
657             destination,
658             errno,
659             strerror(errno)
660         );
661
662         return (-1);
663     }
664
665     return (0);
666 }
667
668 /* Create a temporary file */
669 int mkstemp_ex(char *tmp_path)
670 {
671     int fd;
672
673     fd = mkstemp(tmp_path);
674
675     if (fd == -1) {
676         log2file(
677             MKSTEMP_ERROR,
678             __local_name,
679             tmp_path,
680             errno,
681             strerror(errno)
682         );
683
684         return (-1);
685     }
686
687     /* mkstemp() only implicitly does this in POSIX 2008 */
688     if (fchmod(fd, 0600) == -1) {
689         close(fd);
690
691         log2file(
692             CHMOD_ERROR,
693             __local_name,
694             tmp_path,
695             errno,
696             strerror(errno)
697         );
698
699         if (unlink(tmp_path)) {
700             log2file(
701                 DELETE_ERROR,
702                 __local_name,
703                 tmp_path,
704                 errno,
705                 strerror(errno)
706             );
707         }
708
709         return (-1);
710     }
711
712     close(fd);
713     return (0);
714 }
715
716
717
718 /* getuname; Get uname and returns a string with it.
719  * Memory must be freed after use
720  */
721 char *getuname()
722 {
723     struct utsname uts_buf;
724
725     if(uname(&uts_buf) >= 0)
726     {
727         char *ret;
728
729         ret = calloc(256, sizeof(char));
730         if(ret == NULL)
731             return(NULL);
732
733         snprintf(ret, 255, "%s %s %s %s %s - %s %s",
734                                  uts_buf.sysname,
735                                  uts_buf.nodename,
736                                  uts_buf.release,
737                                  uts_buf.version,
738                                  uts_buf.machine,
739                                  __ossec_name, __version);
740
741         return(ret);
742     }
743     else
744     {
745         char *ret;
746         ret = calloc(256, sizeof(char));
747         if(ret == NULL)
748             return(NULL);
749
750         snprintf(ret, 255, "No system info available -  %s %s",
751                            __ossec_name, __version);
752
753         return(ret);
754     }
755
756     return(NULL);
757 }
758
759
760
761 /* goDaemon: Daemonize a process without closing stdin/stdout/stderr..
762  *
763  */
764 void goDaemonLight()
765 {
766     pid_t pid;
767
768     pid = fork();
769
770     if(pid < 0)
771     {
772         merror(FORK_ERROR, __local_name);
773         return;
774     }
775     else if(pid)
776     {
777         exit(0);
778     }
779
780
781     /* becoming session leader */
782     if(setsid() < 0)
783     {
784         merror(SETSID_ERROR, __local_name);
785         return;
786     }
787
788
789     /* forking again */
790     pid = fork();
791     if(pid < 0)
792     {
793         merror(FORK_ERROR, __local_name);
794         return;
795     }
796     else if(pid)
797     {
798         exit(0);
799     }
800
801
802     dup2(1, 2);
803
804
805     /* Going to / */
806     chdir("/");
807
808
809     return;
810 }
811
812
813
814 /* goDaemon: Daemonize a process..
815  *
816  */
817 void goDaemon()
818 {
819     int fd;
820     pid_t pid;
821
822     pid = fork();
823
824     if(pid < 0)
825     {
826         merror(FORK_ERROR, __local_name);
827         return;
828     }
829     else if(pid)
830     {
831         exit(0);
832     }
833
834     /* becoming session leader */
835     if(setsid() < 0)
836     {
837         merror(SETSID_ERROR, __local_name);
838         return;
839     }
840
841     /* forking again */
842     pid = fork();
843     if(pid < 0)
844     {
845         merror(FORK_ERROR, __local_name);
846         return;
847     }
848     else if(pid)
849     {
850         exit(0);
851     }
852
853
854     /* Dup stdin, stdout and stderr to /dev/null */
855     if((fd = open("/dev/null", O_RDWR)) >= 0)
856     {
857         dup2(fd, 0);
858         dup2(fd, 1);
859         dup2(fd, 2);
860     }
861
862
863     /* Going to / */
864     chdir("/");
865
866
867     /* Closing stdin, stdout and stderr */
868     /*
869     fclose(stdin);
870     fclose(stdout);
871     fclose(stderr);
872     */
873
874     /* Openining stdin, stdout and stderr to /dev/null */
875     /*
876     open("/dev/null", O_RDONLY);
877     open("/dev/null", O_RDWR);
878     open("/dev/null", O_RDWR);
879     */
880
881     return;
882 }
883
884
885 #else
886 int checkVista()
887 {
888     char *m_uname;
889     isVista = 0;
890
891     m_uname = getuname();
892     if(!m_uname)
893     {
894         merror(MEM_ERROR, __local_name);
895         return(0);
896     }
897
898
899     /* We check if the system is vista (must be called during the startup.) */
900     if(strstr(m_uname, "Windows Server 2008") ||
901        strstr(m_uname, "Vista") ||
902        strstr(m_uname, "Windows 7") ||
903        strstr(m_uname, "Windows 8") ||
904        strstr(m_uname, "Windows Server 2012"))
905     {
906         isVista = 1;
907         verbose("%s: INFO: System is Vista or newer (%s).",
908                 __local_name, m_uname);
909     }
910     else
911     {
912         verbose("%s: INFO: System is older than Vista (%s).",
913                 __local_name, m_uname);
914     }
915
916     free(m_uname);
917
918     return(isVista);
919 }
920
921 /* Get basename of path */
922 char *basename_ex(char *path)
923 {
924     return (PathFindFileNameA(path));
925 }
926
927 /* Rename file or directory */
928 int rename_ex(const char *source, const char *destination)
929 {
930     if (!MoveFileEx(source, destination, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
931         log2file(
932             "%s: ERROR: Could not move (%s) to (%s) which returned (%lu)",
933             __local_name,
934             source,
935             destination,
936             GetLastError()
937         );
938
939         return (-1);
940     }
941
942     return (0);
943 }
944
945 /* Create a temporary file */
946 int mkstemp_ex(char *tmp_path)
947 {
948     DWORD dwResult;
949     int result;
950     int status = -1;
951
952     HANDLE h = NULL;
953     PACL pACL = NULL;
954     PSECURITY_DESCRIPTOR pSD = NULL;
955     EXPLICIT_ACCESS ea[2];
956     SECURITY_ATTRIBUTES sa;
957
958     PSID pAdminGroupSID = NULL;
959     PSID pSystemGroupSID = NULL;
960     SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};
961
962 #if defined(_MSC_VER) && _MSC_VER >= 1500
963     result = _mktemp_s(tmp_path, strlen(tmp_path) + 1);
964
965     if (result != 0) {
966         log2file(
967             "%s: ERROR: Could not create temporary file (%s) which returned (%d)",
968             __local_name,
969             tmp_path,
970             result
971         );
972
973         return (-1);
974     }
975 #else
976     if (_mktemp(tmp_path) == NULL) {
977         log2file(
978             "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]",
979             __local_name,
980             tmp_path,
981             errno,
982             strerror(errno)
983         );
984
985         return (-1);
986     }
987 #endif
988
989     /* Create SID for the BUILTIN\Administrators group */
990     result = AllocateAndInitializeSid(
991                  &SIDAuthNT,
992                  2,
993                  SECURITY_BUILTIN_DOMAIN_RID,
994                  DOMAIN_ALIAS_RID_ADMINS,
995                  0, 0, 0, 0, 0, 0,
996                  &pAdminGroupSID
997              );
998
999     if (!result) {
1000         log2file(
1001             "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)",
1002             __local_name,
1003             GetLastError()
1004         );
1005
1006         goto cleanup;
1007     }
1008
1009     /* Create SID for the SYSTEM group */
1010     result = AllocateAndInitializeSid(
1011                  &SIDAuthNT,
1012                  1,
1013                  SECURITY_LOCAL_SYSTEM_RID,
1014                  0, 0, 0, 0, 0, 0, 0,
1015                  &pSystemGroupSID
1016              );
1017
1018     if (!result) {
1019         log2file(
1020             "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)",
1021             __local_name,
1022             GetLastError()
1023         );
1024
1025         goto cleanup;
1026     }
1027
1028     /* Initialize an EXPLICIT_ACCESS structure for an ACE */
1029     ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
1030
1031     /* Add Administrators group */
1032     ea[0].grfAccessPermissions = GENERIC_ALL;
1033     ea[0].grfAccessMode = SET_ACCESS;
1034     ea[0].grfInheritance = NO_INHERITANCE;
1035     ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
1036     ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
1037     ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID;
1038
1039     /* Add SYSTEM group */
1040     ea[1].grfAccessPermissions = GENERIC_ALL;
1041     ea[1].grfAccessMode = SET_ACCESS;
1042     ea[1].grfInheritance = NO_INHERITANCE;
1043     ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
1044     ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
1045     ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID;
1046
1047     /* Set entries in ACL */
1048     dwResult = SetEntriesInAcl(2, ea, NULL, &pACL);
1049
1050     if (dwResult != ERROR_SUCCESS) {
1051         log2file(
1052             "%s: ERROR: Could not set ACL entries which returned (%lu)",
1053             __local_name,
1054             dwResult
1055         );
1056
1057         goto cleanup;
1058     }
1059
1060     /* Initialize security descriptor */
1061     pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(
1062               LPTR,
1063               SECURITY_DESCRIPTOR_MIN_LENGTH
1064           );
1065
1066     if (pSD == NULL) {
1067         log2file(
1068             "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)",
1069             __local_name,
1070             GetLastError()
1071         );
1072
1073         goto cleanup;
1074     }
1075
1076     if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
1077         log2file(
1078             "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)",
1079             __local_name,
1080             GetLastError()
1081         );
1082
1083         goto cleanup;
1084     }
1085
1086     /* Set owner */
1087     if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) {
1088         log2file(
1089             "%s: ERROR: Could not set owner which returned (%lu)",
1090             __local_name,
1091             GetLastError()
1092         );
1093
1094         goto cleanup;
1095     }
1096
1097     /* Set group owner */
1098     if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) {
1099         log2file(
1100             "%s: ERROR: Could not set group owner which returned (%lu)",
1101             __local_name,
1102             GetLastError()
1103         );
1104
1105         goto cleanup;
1106     }
1107
1108     /* Add ACL to security descriptor */
1109     if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
1110         log2file(
1111             "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)",
1112             __local_name,
1113             GetLastError()
1114         );
1115
1116         goto cleanup;
1117     }
1118
1119     /* Initialize security attributes structure */
1120     sa.nLength = sizeof (SECURITY_ATTRIBUTES);
1121     sa.lpSecurityDescriptor = pSD;
1122     sa.bInheritHandle = FALSE;
1123
1124     h = CreateFileA(
1125             tmp_path,
1126             GENERIC_WRITE,
1127             0,
1128             &sa,
1129             CREATE_NEW,
1130             FILE_ATTRIBUTE_NORMAL,
1131             NULL
1132         );
1133
1134     if (h == INVALID_HANDLE_VALUE) {
1135         log2file(
1136             "%s: ERROR: Could not create temporary file (%s) which returned (%lu)",
1137             __local_name,
1138             tmp_path,
1139             GetLastError()
1140         );
1141
1142         goto cleanup;
1143     }
1144
1145     if (!CloseHandle(h)) {
1146         log2file(
1147             "%s: ERROR: Could not close file handle to (%s) which returned (%lu)",
1148             __local_name,
1149             tmp_path,
1150             GetLastError()
1151         );
1152
1153         goto cleanup;
1154     }
1155
1156     /* Success */
1157     status = 0;
1158
1159 cleanup:
1160     if (pAdminGroupSID) {
1161         FreeSid(pAdminGroupSID);
1162     }
1163
1164     if (pSystemGroupSID) {
1165         FreeSid(pSystemGroupSID);
1166     }
1167
1168     if (pACL) {
1169         LocalFree(pACL);
1170     }
1171
1172     if (pSD) {
1173         LocalFree(pSD);
1174     }
1175
1176     return (status);
1177 }
1178
1179
1180 /** get uname for windows **/
1181 char *getuname()
1182 {
1183     int ret_size = OS_SIZE_1024 -2;
1184     char *ret = NULL;
1185     char os_v[128 +1];
1186
1187     typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
1188     typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
1189
1190
1191     /* Extracted from ms web site
1192      * http://msdn.microsoft.com/library/en-us/sysinfo/base/getting_the_system_version.asp
1193      */
1194     OSVERSIONINFOEX osvi;
1195     SYSTEM_INFO si;
1196     PGNSI pGNSI;
1197     PGPI pGPI;
1198     BOOL bOsVersionInfoEx;
1199     DWORD dwType;
1200
1201     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
1202     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1203
1204     if(!(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)))
1205     {
1206         osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1207         if (!GetVersionEx((OSVERSIONINFO *)&osvi))
1208             return(NULL);
1209     }
1210
1211     /* Allocating the memory */
1212     os_calloc(OS_SIZE_1024 +1, sizeof(char), ret);
1213     ret[OS_SIZE_1024] = '\0';
1214
1215     switch(osvi.dwPlatformId)
1216     {
1217         /* Test for the Windows NT product family. */
1218         case VER_PLATFORM_WIN32_NT:
1219             if(osvi.dwMajorVersion == 6)
1220             {
1221                 if(osvi.dwMinorVersion == 0)
1222                 {
1223                     if(osvi.wProductType == VER_NT_WORKSTATION )
1224                         strncat(ret, "Microsoft Windows Vista ", ret_size -1);
1225                     else
1226                     {
1227                         strncat(ret, "Microsoft Windows Server 2008 ", ret_size -1);
1228                     }
1229                 }
1230                 else if(osvi.dwMinorVersion == 1)
1231                 {
1232                     if(osvi.wProductType == VER_NT_WORKSTATION )
1233                         strncat(ret, "Microsoft Windows 7 ", ret_size -1);
1234                     else
1235                     {
1236                         strncat(ret, "Microsoft Windows Server 2008 R2 ", ret_size -1);
1237                     }
1238                 }
1239                 else if(osvi.dwMinorVersion == 2)
1240                 {
1241                     if(osvi.wProductType == VER_NT_WORKSTATION )
1242                         strncat(ret, "Microsoft Windows 8 ", ret_size -1);
1243                     else
1244                     {
1245                         strncat(ret, "Microsoft Windows Server 2012 ", ret_size -1);
1246                     }
1247                 }
1248                 else if(osvi.dwMinorVersion == 3)
1249                 {
1250                     if(osvi.wProductType == VER_NT_WORKSTATION )
1251                         strncat(ret, "Microsoft Windows 8.1 ", ret_size -1);
1252                     else
1253                     {
1254                         strncat(ret, "Microsoft Windows Server 2012 R2 ", ret_size -1);
1255                     }
1256                 }
1257
1258                 ret_size-=strlen(ret) +1;
1259
1260
1261                 /* Getting product version. */
1262                 pGPI = (PGPI) GetProcAddress(
1263                               GetModuleHandle(TEXT("kernel32.dll")),
1264                                                    "GetProductInfo");
1265
1266                 pGPI( 6, 0, 0, 0, &dwType);
1267
1268                 switch(dwType)
1269                 {
1270                     case PRODUCT_UNLICENSED:
1271                         strncat(ret, PRODUCT_UNLICENSED_C, ret_size -1);
1272                         break;
1273                     case PRODUCT_BUSINESS:
1274                         strncat(ret, PRODUCT_BUSINESS_C, ret_size -1);
1275                         break;
1276                     case PRODUCT_BUSINESS_N:
1277                         strncat(ret, PRODUCT_BUSINESS_N_C, ret_size -1);
1278                         break;
1279                     case PRODUCT_CLUSTER_SERVER:
1280                         strncat(ret, PRODUCT_CLUSTER_SERVER_C, ret_size -1);
1281                         break;
1282                     case PRODUCT_DATACENTER_SERVER:
1283                         strncat(ret, PRODUCT_DATACENTER_SERVER_C, ret_size -1);
1284                         break;
1285                     case PRODUCT_DATACENTER_SERVER_CORE:
1286                         strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_C, ret_size -1);
1287                         break;
1288                     case PRODUCT_DATACENTER_SERVER_CORE_V:
1289                         strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_V_C, ret_size -1);
1290                         break;
1291                     case PRODUCT_DATACENTER_SERVER_V:
1292                         strncat(ret, PRODUCT_DATACENTER_SERVER_V_C, ret_size -1);
1293                         break;
1294                     case PRODUCT_ENTERPRISE:
1295                         strncat(ret, PRODUCT_ENTERPRISE_C, ret_size -1);
1296                         break;
1297                     case PRODUCT_ENTERPRISE_N:
1298                         strncat(ret, PRODUCT_ENTERPRISE_N_C, ret_size -1);
1299                         break;
1300                     case PRODUCT_ENTERPRISE_SERVER:
1301                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_C, ret_size -1);
1302                         break;
1303                     case PRODUCT_ENTERPRISE_SERVER_CORE:
1304                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_C, ret_size -1);
1305                         break;
1306                     case PRODUCT_ENTERPRISE_SERVER_CORE_V:
1307                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_V_C, ret_size -1);
1308                         break;
1309                     case PRODUCT_ENTERPRISE_SERVER_IA64:
1310                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_IA64_C, ret_size -1);
1311                         break;
1312                     case PRODUCT_ENTERPRISE_SERVER_V:
1313                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_V_C, ret_size -1);
1314                         break;
1315                     case PRODUCT_HOME_BASIC:
1316                         strncat(ret, PRODUCT_HOME_BASIC_C, ret_size -1);
1317                         break;
1318                     case PRODUCT_HOME_BASIC_N:
1319                         strncat(ret, PRODUCT_HOME_BASIC_N_C, ret_size -1);
1320                         break;
1321                     case PRODUCT_HOME_PREMIUM:
1322                         strncat(ret, PRODUCT_HOME_PREMIUM_C, ret_size -1);
1323                         break;
1324                     case PRODUCT_HOME_PREMIUM_N:
1325                         strncat(ret, PRODUCT_HOME_PREMIUM_N_C, ret_size -1);
1326                         break;
1327                     case PRODUCT_HOME_SERVER:
1328                         strncat(ret, PRODUCT_HOME_SERVER_C, ret_size -1);
1329                         break;
1330                     case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
1331                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C, ret_size -1);
1332                         break;
1333                     case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
1334                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C, ret_size -1);
1335                         break;
1336                     case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
1337                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C, ret_size -1);
1338                         break;
1339                     case PRODUCT_SERVER_FOR_SMALLBUSINESS:
1340                         strncat(ret, PRODUCT_SERVER_FOR_SMALLBUSINESS_C, ret_size -1);
1341                         break;
1342                     case PRODUCT_SMALLBUSINESS_SERVER:
1343                         strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_C, ret_size -1);
1344                         break;
1345                     case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
1346                         strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C, ret_size -1);
1347                         break;
1348                     case PRODUCT_STANDARD_SERVER:
1349                         strncat(ret, PRODUCT_STANDARD_SERVER_C, ret_size -1);
1350                         break;
1351                     case PRODUCT_STANDARD_SERVER_CORE:
1352                         strncat(ret, PRODUCT_STANDARD_SERVER_CORE_C, ret_size -1);
1353                         break;
1354                     case PRODUCT_STANDARD_SERVER_CORE_V:
1355                         strncat(ret, PRODUCT_STANDARD_SERVER_CORE_V_C, ret_size -1);
1356                         break;
1357                     case PRODUCT_STANDARD_SERVER_V:
1358                         strncat(ret, PRODUCT_STANDARD_SERVER_V_C, ret_size -1);
1359                         break;
1360                     case PRODUCT_STARTER:
1361                         strncat(ret, PRODUCT_STARTER_C, ret_size -1);
1362                         break;
1363                     case PRODUCT_STORAGE_ENTERPRISE_SERVER:
1364                         strncat(ret, PRODUCT_STORAGE_ENTERPRISE_SERVER_C, ret_size -1);
1365                         break;
1366                     case PRODUCT_STORAGE_EXPRESS_SERVER:
1367                         strncat(ret, PRODUCT_STORAGE_EXPRESS_SERVER_C, ret_size -1);
1368                         break;
1369                     case PRODUCT_STORAGE_STANDARD_SERVER:
1370                         strncat(ret, PRODUCT_STORAGE_STANDARD_SERVER_C, ret_size -1);
1371                         break;
1372                     case PRODUCT_STORAGE_WORKGROUP_SERVER:
1373                         strncat(ret, PRODUCT_STORAGE_WORKGROUP_SERVER_C, ret_size -1);
1374                         break;
1375                     case PRODUCT_ULTIMATE:
1376                         strncat(ret, PRODUCT_ULTIMATE_C, ret_size -1);
1377                         break;
1378                     case PRODUCT_ULTIMATE_N:
1379                         strncat(ret, PRODUCT_ULTIMATE_N_C, ret_size -1);
1380                         break;
1381                     case PRODUCT_WEB_SERVER:
1382                         strncat(ret, PRODUCT_WEB_SERVER_C, ret_size -1);
1383                         break;
1384                     case PRODUCT_WEB_SERVER_CORE:
1385                         strncat(ret, PRODUCT_WEB_SERVER_CORE_C, ret_size -1);
1386                         break;
1387                 }
1388
1389
1390                 ret_size-=strlen(ret) +1;
1391             }
1392
1393             else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
1394             {
1395                 pGNSI = (PGNSI) GetProcAddress(
1396                         GetModuleHandle("kernel32.dll"),
1397                         "GetNativeSystemInfo");
1398                 if(NULL != pGNSI)
1399                     pGNSI(&si);
1400
1401                 if( GetSystemMetrics(89) )
1402                     strncat(ret, "Microsoft Windows Server 2003 R2 ",
1403                                  ret_size -1);
1404                 else if(osvi.wProductType == VER_NT_WORKSTATION &&
1405                         si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
1406                 {
1407                     strncat(ret,
1408                             "Microsoft Windows XP Professional x64 Edition ",
1409                            ret_size -1 );
1410                 }
1411                 else
1412                 {
1413                     strncat(ret, "Microsoft Windows Server 2003, ",ret_size-1);
1414                 }
1415
1416                 ret_size-=strlen(ret) +1;
1417             }
1418
1419             else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
1420             {
1421                 strncat(ret, "Microsoft Windows XP ", ret_size -1);
1422
1423                 ret_size-=strlen(ret) +1;
1424             }
1425
1426             else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
1427             {
1428                 strncat(ret, "Microsoft Windows 2000 ", ret_size -1);
1429
1430                 ret_size-=strlen(ret) +1;
1431             }
1432
1433             else if (osvi.dwMajorVersion <= 4)
1434             {
1435                 strncat(ret, "Microsoft Windows NT ", ret_size -1);
1436
1437                 ret_size-=strlen(ret) +1;
1438             }
1439             else
1440             {
1441                 strncat(ret, "Microsoft Windows Unknown ", ret_size -1);
1442
1443                 ret_size-=strlen(ret) +1;
1444             }
1445
1446             /* Test for specific product on Windows NT 4.0 SP6 and later. */
1447             if(bOsVersionInfoEx)
1448             {
1449                 /* Test for the workstation type. */
1450                 if (osvi.wProductType == VER_NT_WORKSTATION &&
1451                     si.wProcessorArchitecture!=PROCESSOR_ARCHITECTURE_AMD64)
1452                 {
1453                     if( osvi.dwMajorVersion == 4 )
1454                         strncat(ret, "Workstation 4.0 ", ret_size -1);
1455                     else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
1456                         strncat(ret, "Home Edition ", ret_size -1);
1457                     else
1458                         strncat(ret, "Professional ",ret_size -1);
1459
1460                     /* Fixing size */
1461                     ret_size-=strlen(ret) +1;
1462                 }
1463
1464                 /* Test for the server type. */
1465                 else if( osvi.wProductType == VER_NT_SERVER ||
1466                         osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )
1467                 {
1468                     if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==2)
1469                     {
1470                         if (si.wProcessorArchitecture==
1471                             PROCESSOR_ARCHITECTURE_IA64 )
1472                         {
1473                             if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1474                                 strncat(ret,
1475                                 "Datacenter Edition for Itanium-based Systems ",
1476                                 ret_size -1);
1477                             else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1478                                 strncat(ret,
1479                                 "Enterprise Edition for Itanium-based Systems ",
1480                                  ret_size -1);
1481
1482                             ret_size-=strlen(ret) +1;
1483                         }
1484
1485                         else if ( si.wProcessorArchitecture==
1486                                 PROCESSOR_ARCHITECTURE_AMD64 )
1487                         {
1488                             if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1489                                 strncat(ret, "Datacenter x64 Edition ",
1490                                              ret_size -1 );
1491                             else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1492                                 strncat(ret, "Enterprise x64 Edition ",
1493                                              ret_size -1 );
1494                             else
1495                                 strncat(ret, "Standard x64 Edition ",
1496                                              ret_size -1 );
1497
1498                             ret_size-=strlen(ret) +1;
1499                         }
1500
1501                         else
1502                         {
1503                             if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1504                                 strncat(ret, "Datacenter Edition ",
1505                                               ret_size -1 );
1506                             else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1507                                 strncat(ret,"Enterprise Edition ",ret_size -1);
1508                             else if ( osvi.wSuiteMask == VER_SUITE_BLADE )
1509                                 strncat(ret,"Web Edition ",ret_size -1 );
1510                             else
1511                                 strncat(ret, "Standard Edition ",ret_size -1);
1512
1513                             ret_size-=strlen(ret) +1;
1514                         }
1515                     }
1516                     else if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0)
1517                     {
1518                         if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1519                             strncat(ret, "Datacenter Server ",ret_size -1);
1520                         else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1521                             strncat(ret, "Advanced Server ",ret_size -1 );
1522                         else
1523                             strncat(ret, "Server ",ret_size -1);
1524
1525                         ret_size-=strlen(ret) +1;
1526                     }
1527                     else if(osvi.dwMajorVersion <= 4)  /* Windows NT 4.0  */
1528                     {
1529                         if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1530                             strncat(ret, "Server 4.0, Enterprise Edition ",
1531                                          ret_size -1 );
1532                         else
1533                             strncat(ret, "Server 4.0 ",ret_size -1);
1534
1535                         ret_size-=strlen(ret) +1;
1536                     }
1537                 }
1538             }
1539             /* Test for specific product on Windows NT 4.0 SP5 and earlier */
1540             else
1541             {
1542                 HKEY hKey;
1543                 char szProductType[81];
1544                 DWORD dwBufLen=80;
1545                 LONG lRet;
1546
1547                 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
1548                         "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
1549                         0, KEY_QUERY_VALUE, &hKey );
1550                 if(lRet == ERROR_SUCCESS)
1551                 {
1552                     char __wv[32];
1553
1554                     lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL,
1555                             (LPBYTE) szProductType, &dwBufLen);
1556                     RegCloseKey( hKey );
1557
1558                     if((lRet == ERROR_SUCCESS) && (dwBufLen < 80) )
1559                     {
1560                         if (lstrcmpi( "WINNT", szProductType) == 0 )
1561                             strncat(ret, "Workstation ",ret_size -1);
1562                         else if(lstrcmpi( "LANMANNT", szProductType) == 0 )
1563                             strncat(ret, "Server ",ret_size -1);
1564                         else if(lstrcmpi( "SERVERNT", szProductType) == 0 )
1565                             strncat(ret, "Advanced Server " ,ret_size -1);
1566
1567                         ret_size-=strlen(ret) +1;
1568
1569                         memset(__wv, '\0', 32);
1570                         snprintf(__wv, 31,
1571                                 "%d.%d ",
1572                                 (int)osvi.dwMajorVersion,
1573                                 (int)osvi.dwMinorVersion);
1574
1575                         strncat(ret, __wv, ret_size -1);
1576                         ret_size-=strlen(__wv) +1;
1577                     }
1578                 }
1579             }
1580
1581             /* Display service pack (if any) and build number. */
1582
1583             if( osvi.dwMajorVersion == 4 &&
1584                     lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 )
1585             {
1586                 HKEY hKey;
1587                 LONG lRet;
1588                 char __wp[64];
1589
1590                 memset(__wp, '\0', 64);
1591                 /* Test for SP6 versus SP6a. */
1592                 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
1593                         "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
1594                         0, KEY_QUERY_VALUE, &hKey );
1595                 if( lRet == ERROR_SUCCESS )
1596                     snprintf(__wp, 63, "Service Pack 6a (Build %d)",
1597                             (int)osvi.dwBuildNumber & 0xFFFF );
1598                 else /* Windows NT 4.0 prior to SP6a */
1599                 {
1600                     snprintf(__wp, 63, "%s (Build %d)",
1601                             osvi.szCSDVersion,
1602                             (int)osvi.dwBuildNumber & 0xFFFF);
1603                 }
1604
1605                 strncat(ret, __wp, ret_size -1);
1606                 ret_size-=strlen(__wp) +1;
1607                 RegCloseKey( hKey );
1608             }
1609             else
1610             {
1611                 char __wp[64];
1612
1613                 memset(__wp, '\0', 64);
1614
1615                 snprintf(__wp, 63, "%s (Build %d)",
1616                         osvi.szCSDVersion,
1617                         (int)osvi.dwBuildNumber & 0xFFFF);
1618
1619                 strncat(ret, __wp, ret_size -1);
1620                 ret_size-=strlen(__wp) +1;
1621             }
1622             break;
1623
1624         /* Test for the Windows Me/98/95. */
1625         case VER_PLATFORM_WIN32_WINDOWS:
1626
1627             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
1628             {
1629                 strncat(ret, "Microsoft Windows 95 ", ret_size -1);
1630                 ret_size-=strlen(ret) +1;
1631             }
1632
1633             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
1634             {
1635                 strncat(ret, "Microsoft Windows 98 ", ret_size -1);
1636                 ret_size-=strlen(ret) +1;
1637             }
1638
1639             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
1640             {
1641                 strncat(ret, "Microsoft Windows Millennium Edition",
1642                         ret_size -1);
1643
1644                 ret_size-=strlen(ret) +1;
1645             }
1646             break;
1647
1648         case VER_PLATFORM_WIN32s:
1649
1650             strncat(ret, "Microsoft Win32s", ret_size -1);
1651             ret_size-=strlen(ret) +1;
1652             break;
1653     }
1654
1655
1656     /* Adding ossec version */
1657     snprintf(os_v, 128, " - %s %s", __ossec_name, __version);
1658     strncat(ret, os_v, ret_size -1);
1659
1660
1661     /* Returning system information */
1662     return(ret);
1663
1664 }
1665 #endif
1666
1667 /* EOF */