comparison common/util.c @ 983:427e2e18b8c8

Move Shell functions into util Due to a bug in mingw only one c file may include shlobj.h as there is an unguarded inline definition in there leading to multiple definition errors. Thus the get_program_data get_program_files utility functions.
author Andre Heinecke <andre.heinecke@intevation.de>
date Fri, 29 Aug 2014 17:11:35 +0200
parents 698b6a9bd75e
children 1c1964c27b39 6684e5012b7a
comparison
equal deleted inserted replaced
982:85c497b45488 983:427e2e18b8c8
15 #include <pwd.h> 15 #include <pwd.h>
16 #include <grp.h> 16 #include <grp.h>
17 #include <string.h> 17 #include <string.h>
18 #else 18 #else
19 #include <windows.h> 19 #include <windows.h>
20 #include <accctrl.h>
21 #include <aclapi.h>
22 #include <shlobj.h>
20 #endif 23 #endif
21 24
22 #ifndef APPNAME 25 #ifndef APPNAME
23 #define APPNAME "TrustBridge" 26 #define APPNAME "TrustBridge"
24 #endif 27 #endif
424 CloseHandle (hToken); 427 CloseHandle (hToken);
425 #endif 428 #endif
426 return ret; 429 return ret;
427 } 430 }
428 431
432 #ifdef _WIN32
433 char *
434 get_program_files_folder ()
435 {
436 wchar_t *folder_name = NULL;
437 char *retval = NULL;
438 if (SHGetKnownFolderPath (&FOLDERID_ProgramFiles, /* Get program data dir */
439 KF_FLAG_NO_ALIAS,
440 INVALID_HANDLE_VALUE, /* Get it for the default user */
441 &folder_name) != S_OK)
442 {
443 PRINTLASTERROR ("Failed to get program files folder.");
444 return NULL;
445 }
446
447 retval = wchar_to_utf8 (folder_name, wcslen(folder_name));
448 CoTaskMemFree (folder_name);
449 return retval;
450 }
451
452 /* This is a bit ridicoulous but necessary as shlobj.h contains an inline
453 definition. So only one C file may include it and thus we have to put
454 all our shlobj calls into one file... */
455 wchar_t *
456 get_program_data_folder ()
457 {
458 wchar_t *folder_name = NULL;
459 if (SHGetKnownFolderPath (&FOLDERID_ProgramData, /* Get program data dir */
460 KF_FLAG_CREATE | /* Create if it does not exist */
461 KF_FLAG_INIT, /* Initialize it if created */
462 INVALID_HANDLE_VALUE, /* Get it for the default user */
463 &folder_name) != S_OK)
464 {
465 PRINTLASTERROR ("Failed to get folder path");
466 return NULL;
467 }
468 return folder_name;
469 }
470 #endif
471
429 bool 472 bool
430 is_admin() 473 is_admin()
431 { 474 {
432 #ifndef _WIN32 475 #ifndef _WIN32
433 struct passwd *current_user = getpwuid (geteuid()); 476 struct passwd *current_user = getpwuid (geteuid());
554 597
555 return retval; 598 return retval;
556 #endif 599 #endif
557 } 600 }
558 601
602 #ifdef WIN32
603 bool
604 create_restricted_directory (LPWSTR path)
605 {
606 bool retval = false;
607 PSID everyone_SID = NULL,
608 admin_SID = NULL;
609 PACL access_control_list = NULL;
610 PSECURITY_DESCRIPTOR descriptor = NULL;
611 EXPLICIT_ACCESS explicit_access[2];
612 SID_IDENTIFIER_AUTHORITY world_identifier = {SECURITY_WORLD_SID_AUTHORITY},
613 admin_identifier = {SECURITY_NT_AUTHORITY};
614 SECURITY_ATTRIBUTES security_attributes;
615
616 ZeroMemory(&security_attributes, sizeof(security_attributes));
617 ZeroMemory(&explicit_access, 2 * sizeof(EXPLICIT_ACCESS));
618
619 /* Create a well-known SID for the Everyone group. */
620 if(!AllocateAndInitializeSid(&world_identifier, /* top-level identifier */
621 1, /* subauthorties count */
622 SECURITY_WORLD_RID, /* Only one authority */
623 0, 0, 0, 0, 0, 0, 0, /* No other authorities*/
624 &everyone_SID))
625 {
626 PRINTLASTERROR ("Failed to allocate world sid.\n");
627 return false;
628 }
629
630 /* Initialize the first EXPLICIT_ACCESS structure for an ACE.
631 to allow everyone read access */
632 explicit_access[0].grfAccessPermissions = GENERIC_READ; /* Give read access */
633 explicit_access[0].grfAccessMode = SET_ACCESS; /* Overwrite other access for all users */
634 explicit_access[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; /* make it stick */
635 explicit_access[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
636 explicit_access[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
637 explicit_access[0].Trustee.ptstrName = (LPTSTR) everyone_SID;
638
639 /* Create the SID for the BUILTIN\Administrators group. */
640 if(!AllocateAndInitializeSid(&admin_identifier,
641 2,
642 SECURITY_BUILTIN_DOMAIN_RID, /*BUILTIN\ */
643 DOMAIN_ALIAS_RID_ADMINS, /*\Administrators */
644 0, 0, 0, 0, 0, 0, /* No other */
645 &admin_SID))
646 {
647 PRINTLASTERROR ("Failed to allocate admin sid.");
648 goto done;
649 }
650
651 /* explicit_access[1] grants admins full rights for this object and inherits
652 it to the children */
653 explicit_access[1].grfAccessPermissions = GENERIC_ALL;
654 explicit_access[1].grfAccessMode = SET_ACCESS;
655 explicit_access[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
656 explicit_access[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
657 explicit_access[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
658 explicit_access[1].Trustee.ptstrName = (LPTSTR) admin_SID;
659
660 /* Set up the ACL structure. */
661 if (ERROR_SUCCESS != SetEntriesInAcl(2, explicit_access, NULL, &access_control_list))
662 {
663 PRINTLASTERROR ("Failed to set up Acl.");
664 goto done;
665 }
666
667 /* Initialize a security descriptor */
668 descriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
669 SECURITY_DESCRIPTOR_MIN_LENGTH);
670 if (descriptor == NULL)
671 {
672 PRINTLASTERROR("Failed to allocate descriptor.");
673 goto done;
674 }
675
676 if (!InitializeSecurityDescriptor(descriptor,
677 SECURITY_DESCRIPTOR_REVISION))
678 {
679 PRINTLASTERROR("Failed to initialize descriptor.");
680 goto done;
681 }
682
683 /* Now we add the ACL to the the descriptor */
684 if (!SetSecurityDescriptorDacl(descriptor,
685 TRUE, /* bDaclPresent flag */
686 access_control_list,
687 FALSE)) /* not a default DACL */
688 {
689 PRINTLASTERROR("Failed to set security descriptor.");
690 goto done;
691 }
692
693 /* Finally set up the security attributes structure */
694 security_attributes.nLength = sizeof (SECURITY_ATTRIBUTES);
695 security_attributes.lpSecurityDescriptor = descriptor;
696 security_attributes.bInheritHandle = FALSE;
697
698 /* Use the security attributes to create the directory */
699 if (!CreateDirectoryW(path, &security_attributes))
700 {
701 DWORD err = GetLastError();
702 if (err == ERROR_ALREADY_EXISTS)
703 {
704 /* Verify that the directory has the correct rights */
705 // TODO
706 retval = true;
707 goto done;
708 }
709 ERRORPRINTF ("Failed to create directory. Err: %lu", err);
710 }
711 retval = true;
712
713 done:
714
715 if (everyone_SID)
716 FreeSid(everyone_SID);
717 if (admin_SID)
718 FreeSid(admin_SID);
719 if (access_control_list)
720 LocalFree(access_control_list);
721 if (descriptor)
722 LocalFree(descriptor);
723
724 return retval;
725 }
726 #endif

http://wald.intevation.org/projects/trustbridge/