Imported Upstream version 2.7
[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
21 /* Vista product information. */
22 #ifdef WIN32
23 #ifndef PRODUCT_UNLICENSED
24 #define PRODUCT_UNLICENSED 0xABCDABCD
25 #define PRODUCT_UNLICENSED_C "Product Unlicensed "
26 #endif
27
28 #ifndef PRODUCT_BUSINESS
29 #define PRODUCT_BUSINESS 0x00000006
30 #define PRODUCT_BUSINESS_C "Business Edition "
31 #endif
32
33 #ifndef PRODUCT_BUSINESS_N
34 #define PRODUCT_BUSINESS_N 0x00000010
35 #define PRODUCT_BUSINESS_N_C "Business Edition "
36 #endif
37
38 #ifndef PRODUCT_CLUSTER_SERVER
39 #define PRODUCT_CLUSTER_SERVER 0x00000012
40 #define PRODUCT_CLUSTER_SERVER_C "Cluster Server Edition "
41 #endif
42
43 #ifndef PRODUCT_DATACENTER_SERVER
44 #define PRODUCT_DATACENTER_SERVER 0x00000008
45 #define PRODUCT_DATACENTER_SERVER_C "Datacenter Edition (full) "
46 #endif
47
48 #ifndef PRODUCT_DATACENTER_SERVER_CORE
49 #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
50 #define PRODUCT_DATACENTER_SERVER_CORE_C "Datacenter Edition (core) "
51 #endif
52
53 #ifndef PRODUCT_DATACENTER_SERVER_CORE_V
54 #define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
55 #define PRODUCT_DATACENTER_SERVER_CORE_V_C "Datacenter Edition (core) "
56 #endif
57
58 #ifndef PRODUCT_DATACENTER_SERVER_V
59 #define PRODUCT_DATACENTER_SERVER_V 0x00000025
60 #define PRODUCT_DATACENTER_SERVER_V_C "Datacenter Edition (full) "
61 #endif
62
63 #ifndef PRODUCT_ENTERPRISE
64 #define PRODUCT_ENTERPRISE 0x00000004
65 #define PRODUCT_ENTERPRISE_C "Enterprise Edition "
66 #endif
67
68 #ifndef PRODUCT_ENTERPRISE_N
69 #define PRODUCT_ENTERPRISE_N 0x0000001B
70 #define PRODUCT_ENTERPRISE_N_C "Enterprise Edition "
71 #endif
72
73 #ifndef PRODUCT_ENTERPRISE_SERVER
74 #define PRODUCT_ENTERPRISE_SERVER 0x0000000A
75 #define PRODUCT_ENTERPRISE_SERVER_C "Enterprise Edition (full) "
76 #endif
77
78 #ifndef PRODUCT_ENTERPRISE_SERVER_CORE
79 #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
80 #define PRODUCT_ENTERPRISE_SERVER_CORE_C "Enterprise Edition (core) "
81 #endif
82
83 #ifndef PRODUCT_ENTERPRISE_SERVER_CORE_V
84 #define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
85 #define PRODUCT_ENTERPRISE_SERVER_CORE_V_C "Enterprise Edition (core) "
86 #endif
87
88 #ifndef PRODUCT_ENTERPRISE_SERVER_IA64
89 #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
90 #define PRODUCT_ENTERPRISE_SERVER_IA64_C "Enterprise Edition for Itanium-based Systems "
91 #endif
92
93 #ifndef PRODUCT_ENTERPRISE_SERVER_V
94 #define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
95 #define PRODUCT_ENTERPRISE_SERVER_V_C "Enterprise Edition (full) "
96 #endif
97
98 #ifndef PRODUCT_HOME_BASIC
99 #define PRODUCT_HOME_BASIC 0x00000002
100 #define PRODUCT_HOME_BASIC_C "Home Basic Edition "
101 #endif
102
103 #ifndef PRODUCT_HOME_BASIC_N
104 #define PRODUCT_HOME_BASIC_N 0x00000005
105 #define PRODUCT_HOME_BASIC_N_C "Home Basic Edition "
106 #endif
107
108 #ifndef PRODUCT_HOME_PREMIUM
109 #define PRODUCT_HOME_PREMIUM 0x00000003
110 #define PRODUCT_HOME_PREMIUM_C "Home Premium Edition "
111 #endif
112
113 #ifndef PRODUCT_HOME_PREMIUM_N
114 #define PRODUCT_HOME_PREMIUM_N 0x0000001A
115 #define PRODUCT_HOME_PREMIUM_N_C "Home Premium Edition "
116 #endif
117
118 #ifndef PRODUCT_HOME_SERVER
119 #define PRODUCT_HOME_SERVER 0x00000013
120 #define PRODUCT_HOME_SERVER_C "Home Server Edition "
121 #endif
122
123 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT
124 #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
125 #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C "Essential Business Server Management Server "
126 #endif
127
128 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING
129 #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
130 #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C "Essential Business Server Messaging Server "
131 #endif
132
133 #ifndef PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY
134 #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
135 #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C "Essential Business Server Security Server "
136 #endif
137
138 #ifndef PRODUCT_SERVER_FOR_SMALLBUSINESS
139 #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
140 #define PRODUCT_SERVER_FOR_SMALLBUSINESS_C "Small Business Edition "
141 #endif
142
143 #ifndef PRODUCT_SMALLBUSINESS_SERVER
144 #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
145 #define PRODUCT_SMALLBUSINESS_SERVER_C "Small Business Server "
146 #endif
147
148 #ifndef PRODUCT_SMALLBUSINESS_SERVER_PREMIUM
149 #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
150 #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C "Small Business Server Premium Edition "
151 #endif
152
153 #ifndef PRODUCT_STANDARD_SERVER
154 #define PRODUCT_STANDARD_SERVER 0x00000007
155 #define PRODUCT_STANDARD_SERVER_C "Standard Edition "
156 #endif
157
158 #ifndef PRODUCT_STANDARD_SERVER_CORE
159 #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
160 #define PRODUCT_STANDARD_SERVER_CORE_C "Standard Edition (core) "
161 #endif
162
163 #ifndef PRODUCT_STANDARD_SERVER_CORE_V
164 #define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
165 #define PRODUCT_STANDARD_SERVER_CORE_V_C "Standard Edition "
166 #endif
167
168 #ifndef PRODUCT_STANDARD_SERVER_V
169 #define PRODUCT_STANDARD_SERVER_V 0x00000024
170 #define PRODUCT_STANDARD_SERVER_V_C "Standard Edition "
171 #endif
172
173 #ifndef PRODUCT_STARTER
174 #define PRODUCT_STARTER 0x0000000B
175 #define PRODUCT_STARTER_C "Starter Edition "
176 #endif
177
178 #ifndef PRODUCT_STORAGE_ENTERPRISE_SERVER
179 #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
180 #define PRODUCT_STORAGE_ENTERPRISE_SERVER_C "Storage Server Enterprise Edition "
181 #endif
182
183 #ifndef PRODUCT_STORAGE_EXPRESS_SERVER
184 #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
185 #define PRODUCT_STORAGE_EXPRESS_SERVER_C "Storage Server Express Edition "
186 #endif
187
188 #ifndef PRODUCT_STORAGE_STANDARD_SERVER
189 #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
190 #define PRODUCT_STORAGE_STANDARD_SERVER_C "Storage Server Standard Edition "
191 #endif
192
193 #ifndef PRODUCT_STORAGE_WORKGROUP_SERVER
194 #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
195 #define PRODUCT_STORAGE_WORKGROUP_SERVER_C "Storage Server Workgroup Edition "
196 #endif
197
198 #ifndef PRODUCT_ULTIMATE
199 #define PRODUCT_ULTIMATE 0x00000001
200 #define PRODUCT_ULTIMATE_C "Ultimate Edition "
201 #endif
202
203 #ifndef PRODUCT_ULTIMATE_N
204 #define PRODUCT_ULTIMATE_N 0x0000001C
205 #define PRODUCT_ULTIMATE_N_C "Ultimate Edition "
206 #endif
207
208 #ifndef PRODUCT_WEB_SERVER
209 #define PRODUCT_WEB_SERVER 0x00000011
210 #define PRODUCT_WEB_SERVER_C "Web Server Edition "
211 #endif
212
213 #ifndef PRODUCT_WEB_SERVER_CORE
214 #define PRODUCT_WEB_SERVER_CORE 0x0000001D
215 #define PRODUCT_WEB_SERVER_CORE_C "Web Server Edition "
216 #endif
217 #endif /* WIN32 */
218
219
220
221 /* Sets the name of the starting program */
222 void OS_SetName(char *name)
223 {
224     __local_name = name;
225     return;
226 }
227
228
229 int File_DateofChange(char *file)
230 {
231     struct stat file_status;
232
233     if(stat(file, &file_status) < 0)
234         return(-1);
235
236     return (file_status.st_mtime);
237 }
238
239 int IsDir(char *file)
240 {
241     struct stat file_status;
242     if(stat(file,&file_status) < 0)
243         return(-1);
244     if(S_ISDIR(file_status.st_mode))
245         return(0);
246     return(-1);
247 }
248
249
250 int CreatePID(char *name, int pid)
251 {
252     char file[256];
253     FILE *fp;
254
255     if(isChroot())
256     {
257         snprintf(file,255,"%s/%s-%d.pid",OS_PIDFILE,name,pid);
258     }
259     else
260     {
261         snprintf(file,255,"%s%s/%s-%d.pid",DEFAULTDIR,
262                 OS_PIDFILE,name,pid);
263     }
264
265     fp = fopen(file,"a");
266     if(!fp)
267         return(-1);
268
269     fprintf(fp,"%d\n",pid);
270
271     chmod(file, 0640);
272
273     fclose(fp);
274
275     return(0);
276 }
277
278 int DeletePID(char *name)
279 {
280     char file[256];
281
282     if(isChroot())
283     {
284         snprintf(file,255,"%s/%s-%d.pid",OS_PIDFILE,name,(int)getpid());
285     }
286     else
287     {
288         snprintf(file,255,"%s%s/%s-%d.pid",DEFAULTDIR,
289                 OS_PIDFILE,name,(int)getpid());
290     }
291
292     if(File_DateofChange(file) < 0)
293         return(-1);
294
295     unlink(file);       
296
297     return(0);
298 }
299
300
301 int UnmergeFiles(char *finalpath, char *optdir)
302 {
303     int i = 0, n = 0, ret = 1;
304     long files_size = 0;
305
306     char *files;
307     char final_name[2048 +1];
308     char buf[2048 + 1];
309     FILE *fp;
310     FILE *finalfp;
311
312     finalfp = fopen(finalpath, "r");
313     if(!finalfp)
314     {
315         merror("%s: ERROR: Unable to read merged file: '%s'.",
316                 __local_name, finalpath);
317         return(0);
318     }
319
320     while(1)
321     {
322         /* Reading header portion. */
323         if(fgets(buf, sizeof(buf) -1, finalfp) == NULL)
324         {
325             break;
326         }
327
328
329         /* Initiator. */
330         if(buf[0] != '!')
331             continue;
332
333
334         /* Getting file size and name. */
335         files_size = atol(buf +1);
336
337         files = strchr(buf, '\n');
338         if(files)
339             *files = '\0';
340
341         files = strchr(buf, ' ');
342         if(!files)
343         {
344             ret = 0;
345             continue;
346         }
347         files++;
348
349
350         if(optdir)
351         {
352             snprintf(final_name, 2048, "%s/%s", optdir, files);
353         }
354         else
355         {
356             strncpy(final_name, files, 2048);
357             final_name[2048] = '\0';
358         }
359
360
361         /* Opening file name. */
362         fp = fopen(final_name,"w");
363         if(!fp)
364         {
365             ret = 0;
366             merror("%s: ERROR: Unable to unmerge file '%s'.",
367                     __local_name, final_name);
368         }
369
370
371         if(files_size < sizeof(buf) -1)
372         {
373             i = files_size;
374             files_size = 0;
375         }
376         else
377         {
378             i = sizeof(buf) -1;
379             files_size -= sizeof(buf) -1;
380         }
381
382         while((n = fread(buf, 1, i, finalfp)) > 0)
383         {
384             buf[n] = '\0';
385
386             if(fp)
387             {
388                 fwrite(buf, n, 1, fp);
389             }
390
391             if(files_size == 0)
392             {
393                 break;
394             }
395             else
396             {
397                 if(files_size < sizeof(buf) -1)
398                 {
399                     i = files_size;
400                     files_size = 0;
401                 }
402                 else
403                 {
404                     i = sizeof(buf) -1;
405                     files_size -= sizeof(buf) -1;
406                 }
407             }
408         }
409
410         if(fp)
411             fclose(fp);
412     }
413
414     fclose(finalfp);
415     return(ret);
416 }
417
418
419 int MergeAppendFile(char *finalpath, char *files)
420 {
421     int n = 0;
422     long files_size = 0;
423
424     char buf[2048 + 1];
425     char *tmpfile;
426     FILE *fp;
427     FILE *finalfp;
428
429
430     /* Creating a new entry. */
431     if(files == NULL)
432     {
433         finalfp = fopen(finalpath, "w");
434         if(!finalfp)
435         {
436             merror("%s: ERROR: Unable to create merged file: '%s'.",
437                     __local_name, finalpath);
438             return(0);
439         }
440         fclose(finalfp);
441
442         return(1);
443     }
444
445
446     finalfp = fopen(finalpath, "a");
447     if(!finalfp)
448     {
449         merror("%s: ERROR: Unable to create merged file: '%s'.",
450                 __local_name, finalpath);
451         return(0);
452     }
453
454
455     fp = fopen(files,"r");
456     if(!fp)
457     {
458         merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files);
459         fclose(finalfp);
460         return(0);
461     }
462
463
464     fseek(fp, 0, SEEK_END);
465     files_size = ftell(fp);
466
467     tmpfile = strrchr(files, '/');
468     if(tmpfile)
469     {
470         tmpfile++;
471     }
472     else
473     {
474         tmpfile = files;
475     }
476     fprintf(finalfp, "!%ld %s\n", files_size, tmpfile);
477
478     fseek(fp, 0, SEEK_SET);
479
480     while((n = fread(buf, 1, sizeof(buf) -1, fp)) > 0)
481     {
482         buf[n] = '\0';
483         fwrite(buf, n, 1, finalfp);
484     }
485
486     fclose(fp);
487
488     fclose(finalfp);
489     return(1);
490 }
491
492
493
494 int MergeFiles(char *finalpath, char **files)
495 {
496     int i = 0, n = 0, ret = 1;
497     long files_size = 0;
498
499     char *tmpfile;
500     char buf[2048 + 1];
501     FILE *fp;
502     FILE *finalfp;
503
504     finalfp = fopen(finalpath, "w");
505     if(!finalfp)
506     {
507         merror("%s: ERROR: Unable to create merged file: '%s'.",
508                __local_name, finalpath);
509         return(0);
510     }
511
512     while(files[i])
513     {
514         fp = fopen(files[i],"r");
515         if(!fp)
516         {
517             merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files[i]);
518             i++;
519             ret = 0;
520             continue;
521         }
522
523         fseek(fp, 0, SEEK_END);
524         files_size = ftell(fp);
525
526         /* Removing last entry. */
527         tmpfile = strrchr(files[i], '/');
528         if(tmpfile)
529         {
530             tmpfile++;
531         }
532         else
533         {
534             tmpfile = files[i];
535         }
536
537         fprintf(finalfp, "!%ld %s\n", files_size, tmpfile);
538
539         fseek(fp, 0, SEEK_SET);
540
541         while((n = fread(buf, 1, sizeof(buf) -1, fp)) > 0)
542         {
543             buf[n] = '\0';
544             fwrite(buf, n, 1, finalfp);
545         }
546
547         fclose(fp);
548         i++;
549     }
550
551     fclose(finalfp);
552     return(ret);
553 }
554
555
556 #ifndef WIN32
557 /* getuname; Get uname and returns a string with it.
558  * Memory must be freed after use
559  */
560 char *getuname()
561 {
562     struct utsname uts_buf;
563
564     if(uname(&uts_buf) >= 0)
565     {
566         char *ret;
567
568         ret = calloc(256, sizeof(char));
569         if(ret == NULL)
570             return(NULL);
571
572         snprintf(ret, 255, "%s %s %s %s %s - %s %s",
573                                  uts_buf.sysname,
574                                  uts_buf.nodename,
575                                  uts_buf.release,
576                                  uts_buf.version,
577                                  uts_buf.machine,
578                                  __name, __version);
579
580         return(ret);
581     }
582     else
583     {
584         char *ret;
585         ret = calloc(256, sizeof(char));
586         if(ret == NULL)
587             return(NULL);
588
589         snprintf(ret, 255, "No system info available -  %s %s",
590                            __name, __version);
591
592         return(ret);
593     }
594
595     return(NULL);
596 }
597
598
599
600 /* goDaemon: Daemonize a process without closing stdin/stdout/stderr..
601  *
602  */
603 void goDaemonLight()
604 {
605     pid_t pid;
606
607     pid = fork();
608
609     if(pid < 0)
610     {
611         merror(FORK_ERROR, __local_name);
612         return;
613     }
614     else if(pid)
615     {
616         exit(0);
617     }
618
619
620     /* becoming session leader */
621     if(setsid() < 0)
622     {
623         merror(SETSID_ERROR, __local_name);
624         return;
625     }
626
627
628     /* forking again */
629     pid = fork();
630     if(pid < 0)
631     {
632         merror(FORK_ERROR, __local_name);
633         return;
634     }
635     else if(pid)
636     {
637         exit(0);
638     }
639
640
641     dup2(1, 2);
642
643
644     /* Going to / */
645     chdir("/");
646
647
648     return;
649 }
650
651
652
653 /* goDaemon: Daemonize a process..
654  *
655  */
656 void goDaemon()
657 {
658     int fd;
659     pid_t pid;
660
661     pid = fork();
662
663     if(pid < 0)
664     {
665         merror(FORK_ERROR, __local_name);
666         return;
667     }
668     else if(pid)
669     {
670         exit(0);
671     }
672
673     /* becoming session leader */
674     if(setsid() < 0)
675     {
676         merror(SETSID_ERROR, __local_name);
677         return;
678     }
679
680     /* forking again */
681     pid = fork();
682     if(pid < 0)
683     {
684         merror(FORK_ERROR, __local_name);
685         return;
686     }
687     else if(pid)
688     {
689         exit(0);
690     }
691
692
693     /* Dup stdin, stdout and stderr to /dev/null */
694     if((fd = open("/dev/null", O_RDWR)) >= 0)
695     {
696         dup2(fd, 0);
697         dup2(fd, 1);
698         dup2(fd, 2);
699     }
700
701
702     /* Going to / */
703     chdir("/");
704
705
706     /* Closing stdin, stdout and stderr */
707     /*
708     fclose(stdin);
709     fclose(stdout);
710     fclose(stderr);
711     */
712
713     /* Openining stdin, stdout and stderr to /dev/null */
714     /*
715     open("/dev/null", O_RDONLY);
716     open("/dev/null", O_RDWR);
717     open("/dev/null", O_RDWR);
718     */
719
720     return;
721 }
722
723
724 #else
725 int checkVista()
726 {
727     char *m_uname;
728     isVista = 0;
729
730     m_uname = getuname();
731     if(!m_uname)
732     {
733         merror(MEM_ERROR, __local_name);
734         return(0);
735     }
736
737
738     /* We check if the system is vista (must be called during the startup.) */
739     if(strstr(m_uname, "Windows Server 2008") ||
740        strstr(m_uname, "Vista") ||
741        strstr(m_uname, "Windows 7"))
742     {
743         isVista = 1;
744         verbose("%s: INFO: System is Vista or Windows Server 2008.",
745                 __local_name);
746     }
747
748     free(m_uname);
749
750     return(isVista);
751 }
752
753
754
755 /** get uname for windows **/
756 char *getuname()
757 {
758     int ret_size = OS_SIZE_1024 -2;
759     char *ret = NULL;
760     char os_v[128 +1];
761
762     typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
763     typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
764
765
766     /* Extracted from ms web site
767      * http://msdn.microsoft.com/library/en-us/sysinfo/base/getting_the_system_version.asp
768      */
769     OSVERSIONINFOEX osvi;
770     SYSTEM_INFO si;
771     PGNSI pGNSI;
772     PGPI pGPI;
773     BOOL bOsVersionInfoEx;
774     DWORD dwType;
775
776     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
777     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
778
779     if(!(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)))
780     {
781         osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
782         if (!GetVersionEx((OSVERSIONINFO *)&osvi))
783             return(NULL);
784     }
785
786     /* Allocating the memory */
787     os_calloc(OS_SIZE_1024 +1, sizeof(char), ret);
788     ret[OS_SIZE_1024] = '\0';
789
790     switch(osvi.dwPlatformId)
791     {
792         /* Test for the Windows NT product family. */
793         case VER_PLATFORM_WIN32_NT:
794             if(osvi.dwMajorVersion == 6)
795             {
796                 if(osvi.dwMinorVersion == 0)
797                 {
798                     if(osvi.wProductType == VER_NT_WORKSTATION )
799                         strncat(ret, "Microsoft Windows Vista ", ret_size -1);
800                     else
801                     {
802                         strncat(ret, "Microsoft Windows Server 2008 ", ret_size -1);
803                     }
804                 }
805                 else if(osvi.dwMinorVersion == 1)
806                 {
807                     if(osvi.wProductType == VER_NT_WORKSTATION )
808                         strncat(ret, "Microsoft Windows 7 ", ret_size -1);
809                     else
810                     {
811                         strncat(ret, "Microsoft Windows Server 2008 R2 ", ret_size -1);
812                     }
813                 }
814
815                 ret_size-=strlen(ret) +1;
816
817
818                 /* Getting product version. */
819                 pGPI = (PGPI) GetProcAddress(
820                               GetModuleHandle(TEXT("kernel32.dll")),
821                                                    "GetProductInfo");
822
823                 pGPI( 6, 0, 0, 0, &dwType);
824
825                 switch(dwType)
826                 {
827                     case PRODUCT_UNLICENSED:
828                         strncat(ret, PRODUCT_UNLICENSED_C, ret_size -1);
829                         break;
830                     case PRODUCT_BUSINESS:
831                         strncat(ret, PRODUCT_BUSINESS_C, ret_size -1);
832                         break;
833                     case PRODUCT_BUSINESS_N:
834                         strncat(ret, PRODUCT_BUSINESS_N_C, ret_size -1);
835                         break;
836                     case PRODUCT_CLUSTER_SERVER:
837                         strncat(ret, PRODUCT_CLUSTER_SERVER_C, ret_size -1);
838                         break;
839                     case PRODUCT_DATACENTER_SERVER:
840                         strncat(ret, PRODUCT_DATACENTER_SERVER_C, ret_size -1);
841                         break;
842                     case PRODUCT_DATACENTER_SERVER_CORE:
843                         strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_C, ret_size -1);
844                         break;
845                     case PRODUCT_DATACENTER_SERVER_CORE_V:
846                         strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_V_C, ret_size -1);
847                         break;
848                     case PRODUCT_DATACENTER_SERVER_V:
849                         strncat(ret, PRODUCT_DATACENTER_SERVER_V_C, ret_size -1);
850                         break;
851                     case PRODUCT_ENTERPRISE:
852                         strncat(ret, PRODUCT_ENTERPRISE_C, ret_size -1);
853                         break;
854                     case PRODUCT_ENTERPRISE_N:
855                         strncat(ret, PRODUCT_ENTERPRISE_N_C, ret_size -1);
856                         break;
857                     case PRODUCT_ENTERPRISE_SERVER:
858                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_C, ret_size -1);
859                         break;
860                     case PRODUCT_ENTERPRISE_SERVER_CORE:
861                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_C, ret_size -1);
862                         break;
863                     case PRODUCT_ENTERPRISE_SERVER_CORE_V:
864                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_V_C, ret_size -1);
865                         break;
866                     case PRODUCT_ENTERPRISE_SERVER_IA64:
867                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_IA64_C, ret_size -1);
868                         break;
869                     case PRODUCT_ENTERPRISE_SERVER_V:
870                         strncat(ret, PRODUCT_ENTERPRISE_SERVER_V_C, ret_size -1);
871                         break;
872                     case PRODUCT_HOME_BASIC:
873                         strncat(ret, PRODUCT_HOME_BASIC_C, ret_size -1);
874                         break;
875                     case PRODUCT_HOME_BASIC_N:
876                         strncat(ret, PRODUCT_HOME_BASIC_N_C, ret_size -1);
877                         break;
878                     case PRODUCT_HOME_PREMIUM:
879                         strncat(ret, PRODUCT_HOME_PREMIUM_C, ret_size -1);
880                         break;
881                     case PRODUCT_HOME_PREMIUM_N:
882                         strncat(ret, PRODUCT_HOME_PREMIUM_N_C, ret_size -1);
883                         break;
884                     case PRODUCT_HOME_SERVER:
885                         strncat(ret, PRODUCT_HOME_SERVER_C, ret_size -1);
886                         break;
887                     case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
888                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C, ret_size -1);
889                         break;
890                     case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
891                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C, ret_size -1);
892                         break;
893                     case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
894                         strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C, ret_size -1);
895                         break;
896                     case PRODUCT_SERVER_FOR_SMALLBUSINESS:
897                         strncat(ret, PRODUCT_SERVER_FOR_SMALLBUSINESS_C, ret_size -1);
898                         break;
899                     case PRODUCT_SMALLBUSINESS_SERVER:
900                         strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_C, ret_size -1);
901                         break;
902                     case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
903                         strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C, ret_size -1);
904                         break;
905                     case PRODUCT_STANDARD_SERVER:
906                         strncat(ret, PRODUCT_STANDARD_SERVER_C, ret_size -1);
907                         break;
908                     case PRODUCT_STANDARD_SERVER_CORE:
909                         strncat(ret, PRODUCT_STANDARD_SERVER_CORE_C, ret_size -1);
910                         break;
911                     case PRODUCT_STANDARD_SERVER_CORE_V:
912                         strncat(ret, PRODUCT_STANDARD_SERVER_CORE_V_C, ret_size -1);
913                         break;
914                     case PRODUCT_STANDARD_SERVER_V:
915                         strncat(ret, PRODUCT_STANDARD_SERVER_V_C, ret_size -1);
916                         break;
917                     case PRODUCT_STARTER:
918                         strncat(ret, PRODUCT_STARTER_C, ret_size -1);
919                         break;
920                     case PRODUCT_STORAGE_ENTERPRISE_SERVER:
921                         strncat(ret, PRODUCT_STORAGE_ENTERPRISE_SERVER_C, ret_size -1);
922                         break;
923                     case PRODUCT_STORAGE_EXPRESS_SERVER:
924                         strncat(ret, PRODUCT_STORAGE_EXPRESS_SERVER_C, ret_size -1);
925                         break;
926                     case PRODUCT_STORAGE_STANDARD_SERVER:
927                         strncat(ret, PRODUCT_STORAGE_STANDARD_SERVER_C, ret_size -1);
928                         break;
929                     case PRODUCT_STORAGE_WORKGROUP_SERVER:
930                         strncat(ret, PRODUCT_STORAGE_WORKGROUP_SERVER_C, ret_size -1);
931                         break;
932                     case PRODUCT_ULTIMATE:
933                         strncat(ret, PRODUCT_ULTIMATE_C, ret_size -1);
934                         break;
935                     case PRODUCT_ULTIMATE_N:
936                         strncat(ret, PRODUCT_ULTIMATE_N_C, ret_size -1);
937                         break;
938                     case PRODUCT_WEB_SERVER:
939                         strncat(ret, PRODUCT_WEB_SERVER_C, ret_size -1);
940                         break;
941                     case PRODUCT_WEB_SERVER_CORE:
942                         strncat(ret, PRODUCT_WEB_SERVER_CORE_C, ret_size -1);
943                         break;
944                 }
945
946
947                 ret_size-=strlen(ret) +1;
948             }
949
950             else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
951             {
952                 pGNSI = (PGNSI) GetProcAddress(
953                         GetModuleHandle("kernel32.dll"),
954                         "GetNativeSystemInfo");
955                 if(NULL != pGNSI)
956                     pGNSI(&si);
957
958                 if( GetSystemMetrics(89) )
959                     strncat(ret, "Microsoft Windows Server 2003 R2 ",
960                                  ret_size -1);
961                 else if(osvi.wProductType == VER_NT_WORKSTATION &&
962                         si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
963                 {
964                     strncat(ret,
965                             "Microsoft Windows XP Professional x64 Edition ",
966                            ret_size -1 );
967                 }
968                 else
969                 {
970                     strncat(ret, "Microsoft Windows Server 2003, ",ret_size-1);
971                 }
972
973                 ret_size-=strlen(ret) +1;
974             }
975
976             else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
977             {
978                 strncat(ret, "Microsoft Windows XP ", ret_size -1);
979
980                 ret_size-=strlen(ret) +1;
981             }
982
983             else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
984             {
985                 strncat(ret, "Microsoft Windows 2000 ", ret_size -1);
986
987                 ret_size-=strlen(ret) +1;
988             }
989
990             else if (osvi.dwMajorVersion <= 4)
991             {
992                 strncat(ret, "Microsoft Windows NT ", ret_size -1);
993
994                 ret_size-=strlen(ret) +1;
995             }
996             else
997             {
998                 strncat(ret, "Microsoft Windows Unknown ", ret_size -1);
999
1000                 ret_size-=strlen(ret) +1;
1001             }
1002
1003             /* Test for specific product on Windows NT 4.0 SP6 and later. */
1004             if(bOsVersionInfoEx)
1005             {
1006                 /* Test for the workstation type. */
1007                 if (osvi.wProductType == VER_NT_WORKSTATION &&
1008                     si.wProcessorArchitecture!=PROCESSOR_ARCHITECTURE_AMD64)
1009                 {
1010                     if( osvi.dwMajorVersion == 4 )
1011                         strncat(ret, "Workstation 4.0 ", ret_size -1);
1012                     else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
1013                         strncat(ret, "Home Edition ", ret_size -1);
1014                     else
1015                         strncat(ret, "Professional ",ret_size -1);
1016
1017                     /* Fixing size */
1018                     ret_size-=strlen(ret) +1;
1019                 }
1020
1021                 /* Test for the server type. */
1022                 else if( osvi.wProductType == VER_NT_SERVER ||
1023                         osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )
1024                 {
1025                     if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==2)
1026                     {
1027                         if (si.wProcessorArchitecture==
1028                             PROCESSOR_ARCHITECTURE_IA64 )
1029                         {
1030                             if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1031                                 strncat(ret,
1032                                 "Datacenter Edition for Itanium-based Systems ",
1033                                 ret_size -1);
1034                             else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1035                                 strncat(ret,
1036                                 "Enterprise Edition for Itanium-based Systems ",
1037                                  ret_size -1);
1038
1039                             ret_size-=strlen(ret) +1;
1040                         }
1041
1042                         else if ( si.wProcessorArchitecture==
1043                                 PROCESSOR_ARCHITECTURE_AMD64 )
1044                         {
1045                             if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1046                                 strncat(ret, "Datacenter x64 Edition ",
1047                                              ret_size -1 );
1048                             else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1049                                 strncat(ret, "Enterprise x64 Edition ",
1050                                              ret_size -1 );
1051                             else
1052                                 strncat(ret, "Standard x64 Edition ",
1053                                              ret_size -1 );
1054
1055                             ret_size-=strlen(ret) +1;
1056                         }
1057
1058                         else
1059                         {
1060                             if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1061                                 strncat(ret, "Datacenter Edition ",
1062                                               ret_size -1 );
1063                             else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1064                                 strncat(ret,"Enterprise Edition ",ret_size -1);
1065                             else if ( osvi.wSuiteMask == VER_SUITE_BLADE )
1066                                 strncat(ret,"Web Edition ",ret_size -1 );
1067                             else
1068                                 strncat(ret, "Standard Edition ",ret_size -1);
1069
1070                             ret_size-=strlen(ret) +1;
1071                         }
1072                     }
1073                     else if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0)
1074                     {
1075                         if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
1076                             strncat(ret, "Datacenter Server ",ret_size -1);
1077                         else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1078                             strncat(ret, "Advanced Server ",ret_size -1 );
1079                         else
1080                             strncat(ret, "Server ",ret_size -1);
1081
1082                         ret_size-=strlen(ret) +1;
1083                     }
1084                     else if(osvi.dwMajorVersion <= 4)  /* Windows NT 4.0  */
1085                     {
1086                         if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
1087                             strncat(ret, "Server 4.0, Enterprise Edition ",
1088                                          ret_size -1 );
1089                         else
1090                             strncat(ret, "Server 4.0 ",ret_size -1);
1091
1092                         ret_size-=strlen(ret) +1;
1093                     }
1094                 }
1095             }
1096             /* Test for specific product on Windows NT 4.0 SP5 and earlier */
1097             else
1098             {
1099                 HKEY hKey;
1100                 char szProductType[81];
1101                 DWORD dwBufLen=80;
1102                 LONG lRet;
1103
1104                 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
1105                         "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
1106                         0, KEY_QUERY_VALUE, &hKey );
1107                 if(lRet == ERROR_SUCCESS)
1108                 {
1109                     char __wv[32];
1110
1111                     lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL,
1112                             (LPBYTE) szProductType, &dwBufLen);
1113                     RegCloseKey( hKey );
1114
1115                     if((lRet == ERROR_SUCCESS) && (dwBufLen < 80) )
1116                     {
1117                         if (lstrcmpi( "WINNT", szProductType) == 0 )
1118                             strncat(ret, "Workstation ",ret_size -1);
1119                         else if(lstrcmpi( "LANMANNT", szProductType) == 0 )
1120                             strncat(ret, "Server ",ret_size -1);
1121                         else if(lstrcmpi( "SERVERNT", szProductType) == 0 )
1122                             strncat(ret, "Advanced Server " ,ret_size -1);
1123
1124                         ret_size-=strlen(ret) +1;
1125
1126                         memset(__wv, '\0', 32);
1127                         snprintf(__wv, 31,
1128                                 "%d.%d ",
1129                                 (int)osvi.dwMajorVersion,
1130                                 (int)osvi.dwMinorVersion);
1131
1132                         strncat(ret, __wv, ret_size -1);
1133                         ret_size-=strlen(__wv) +1;
1134                     }
1135                 }
1136             }
1137
1138             /* Display service pack (if any) and build number. */
1139
1140             if( osvi.dwMajorVersion == 4 &&
1141                     lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 )
1142             {
1143                 HKEY hKey;
1144                 LONG lRet;
1145                 char __wp[64];
1146
1147                 memset(__wp, '\0', 64);
1148                 /* Test for SP6 versus SP6a. */
1149                 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
1150                         "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
1151                         0, KEY_QUERY_VALUE, &hKey );
1152                 if( lRet == ERROR_SUCCESS )
1153                     snprintf(__wp, 63, "Service Pack 6a (Build %d)",
1154                             (int)osvi.dwBuildNumber & 0xFFFF );
1155                 else /* Windows NT 4.0 prior to SP6a */
1156                 {
1157                     snprintf(__wp, 63, "%s (Build %d)",
1158                             osvi.szCSDVersion,
1159                             (int)osvi.dwBuildNumber & 0xFFFF);
1160                 }
1161
1162                 strncat(ret, __wp, ret_size -1);
1163                 ret_size-=strlen(__wp) +1;
1164                 RegCloseKey( hKey );
1165             }
1166             else
1167             {
1168                 char __wp[64];
1169
1170                 memset(__wp, '\0', 64);
1171
1172                 snprintf(__wp, 63, "%s (Build %d)",
1173                         osvi.szCSDVersion,
1174                         (int)osvi.dwBuildNumber & 0xFFFF);
1175
1176                 strncat(ret, __wp, ret_size -1);
1177                 ret_size-=strlen(__wp) +1;
1178             }
1179             break;
1180
1181         /* Test for the Windows Me/98/95. */
1182         case VER_PLATFORM_WIN32_WINDOWS:
1183
1184             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
1185             {
1186                 strncat(ret, "Microsoft Windows 95 ", ret_size -1);
1187                 ret_size-=strlen(ret) +1;
1188             }
1189
1190             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
1191             {
1192                 strncat(ret, "Microsoft Windows 98 ", ret_size -1);
1193                 ret_size-=strlen(ret) +1;
1194             }
1195
1196             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
1197             {
1198                 strncat(ret, "Microsoft Windows Millennium Edition",
1199                         ret_size -1);
1200
1201                 ret_size-=strlen(ret) +1;
1202             }
1203             break;
1204
1205         case VER_PLATFORM_WIN32s:
1206
1207             strncat(ret, "Microsoft Win32s", ret_size -1);
1208             ret_size-=strlen(ret) +1;
1209             break;
1210     }
1211
1212
1213     /* Adding ossec version */
1214     snprintf(os_v, 128, " - %s %s", __name, __version);
1215     strncat(ret, os_v, ret_size -1);
1216
1217
1218     /* Returning system information */
1219     return(ret);
1220
1221 }
1222 #endif
1223
1224 /* EOF */