Mercurial > trustbridge
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 |