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