Lines 87-100
Link Here
|
87 |
|
87 |
|
88 |
#include <windows.h> |
88 |
#include <windows.h> |
89 |
#include <aclapi.h> |
89 |
#include <aclapi.h> |
|
|
90 |
#include <lmcons.h> |
90 |
|
91 |
|
91 |
static USHORT os_type; |
92 |
static USHORT os_type; |
92 |
static SECURITY_ATTRIBUTES security_attr; |
93 |
static SECURITY_ATTRIBUTES security_attr; |
93 |
|
94 |
|
94 |
//static TEXT interbase_directory[MAXPATHLEN]; |
95 |
//static TEXT interbase_directory[MAXPATHLEN]; |
95 |
|
96 |
|
96 |
static bool check_user_privilege(); |
|
|
97 |
|
98 |
#endif // WIN_NT |
97 |
#endif // WIN_NT |
99 |
|
98 |
|
100 |
static TEXT user_name[256]; |
99 |
static TEXT user_name[256]; |
Lines 393-406
Link Here
|
393 |
} |
392 |
} |
394 |
#endif |
393 |
#endif |
395 |
|
394 |
|
|
|
395 |
const TEXT* ISC_get_host(Firebird::string& host) |
396 |
{ |
397 |
/************************************** |
398 |
* |
399 |
* I S C _ g e t _ h o s t |
400 |
* |
401 |
************************************** |
402 |
* |
403 |
* Functional description |
404 |
* Get host name in non-plain buffer. |
405 |
* |
406 |
**************************************/ |
407 |
TEXT buffer[BUFFER_SMALL]; |
408 |
ISC_get_host(buffer, sizeof(buffer)); |
409 |
host = buffer; |
410 |
return host.c_str(); |
411 |
} |
412 |
|
396 |
#ifdef UNIX |
413 |
#ifdef UNIX |
397 |
int ISC_get_user(TEXT* name, |
414 |
bool ISC_get_user(Firebird::string* name, |
398 |
int* id, |
415 |
int* id, |
399 |
int* group, |
416 |
int* group, |
400 |
TEXT* project, |
417 |
const TEXT* user_string) |
401 |
TEXT* organization, |
|
|
402 |
int* node, |
403 |
const TEXT* user_string) |
404 |
{ |
418 |
{ |
405 |
/************************************** |
419 |
/************************************** |
406 |
* |
420 |
* |
Lines 448-454
Link Here
|
448 |
} |
462 |
} |
449 |
|
463 |
|
450 |
if (name) |
464 |
if (name) |
451 |
strcpy(name, p); |
465 |
*name = p; |
452 |
|
466 |
|
453 |
if (id) |
467 |
if (id) |
454 |
*id = euid; |
468 |
*id = euid; |
Lines 456-470
Link Here
|
456 |
if (group) |
470 |
if (group) |
457 |
*group = egid; |
471 |
*group = egid; |
458 |
|
472 |
|
459 |
if (project) |
|
|
460 |
*project = 0; |
461 |
|
462 |
if (organization) |
463 |
*organization = 0; |
464 |
|
465 |
if (node) |
466 |
*node = 0; |
467 |
|
468 |
return (euid == 0); |
473 |
return (euid == 0); |
469 |
} |
474 |
} |
470 |
#endif |
475 |
#endif |
Lines 573-585
Link Here
|
573 |
#endif |
578 |
#endif |
574 |
|
579 |
|
575 |
#ifdef WIN_NT |
580 |
#ifdef WIN_NT |
576 |
int ISC_get_user(TEXT* name, |
581 |
bool ISC_get_user(Firebird::string* name, |
577 |
int* id, |
582 |
int* id, |
578 |
int* group, |
583 |
int* group, |
579 |
TEXT* project, |
584 |
const TEXT* user_string) |
580 |
TEXT* organization, |
|
|
581 |
int* node, |
582 |
const TEXT* user_string) |
583 |
{ |
585 |
{ |
584 |
/************************************** |
586 |
/************************************** |
585 |
* |
587 |
* |
Lines 597-758
Link Here
|
597 |
if (group) |
599 |
if (group) |
598 |
*group = -1; |
600 |
*group = -1; |
599 |
|
601 |
|
600 |
if (project) |
|
|
601 |
*project = 0; |
602 |
|
603 |
if (organization) |
604 |
*organization = 0; |
605 |
|
606 |
if (node) |
607 |
*node = 0; |
608 |
|
609 |
if (name) |
602 |
if (name) |
610 |
{ |
603 |
{ |
611 |
name[0] = 0; |
604 |
DWORD name_len = UNLEN; |
612 |
DWORD name_len = 128; |
605 |
TEXT* nm = name->getBuffer(name_len + 1); |
613 |
if (GetUserName(name, &name_len)) |
606 |
if (GetUserName(nm, &name_len)) |
614 |
{ |
|
|
615 |
name[name_len] = 0; |
616 |
|
617 |
/* NT user name is case insensitive */ |
618 |
|
619 |
for (DWORD i = 0; i < name_len; i++) |
620 |
{ |
621 |
name[i] = UPPER7(name[i]); |
622 |
} |
623 |
|
624 |
/* This check is not internationalized, the security model needs to be |
625 |
* reengineered, especially on SUPERSERVER where none of these local |
626 |
* user (in process) assumptions are valid. |
627 |
if (!strcmp(name, "ADMINISTRATOR")) |
628 |
{ |
629 |
if (id) |
630 |
*id = 0; |
631 |
|
632 |
if (group) |
633 |
*group = 0; |
634 |
} |
635 |
*/ |
636 |
} |
637 |
} |
638 |
|
639 |
return check_user_privilege(); |
640 |
} |
641 |
|
642 |
|
643 |
//____________________________________________________________ |
644 |
// |
645 |
// Check to see if the user belongs to the administrator group. |
646 |
// |
647 |
// This routine was adapted from code in routine RunningAsAdminstrator |
648 |
// in \mstools\samples\regmpad\regdb.c. |
649 |
// |
650 |
static bool check_user_privilege() |
651 |
{ |
652 |
HANDLE tkhandle; |
653 |
SID_IDENTIFIER_AUTHORITY system_sid_authority = {SECURITY_NT_AUTHORITY}; |
654 |
|
655 |
// First we must open a handle to the access token for this thread. |
656 |
|
657 |
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &tkhandle)) |
658 |
{ |
659 |
if (GetLastError() == ERROR_NO_TOKEN) |
660 |
{ |
607 |
{ |
661 |
// If the thread does not have an access token, we'll examine the |
608 |
nm[name_len] = 0; |
662 |
// access token associated with the process. |
|
|
663 |
|
609 |
|
664 |
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkhandle)) |
610 |
// NT user name is case insensitive |
665 |
{ |
611 |
CharUpperBuff(nm, name_len); |
666 |
CloseHandle(tkhandle); |
612 |
name->recalculate_length(); |
667 |
return false; |
|
|
668 |
} |
669 |
} |
613 |
} |
670 |
else |
614 |
else |
671 |
{ |
615 |
{ |
672 |
return false; |
616 |
*name = ""; |
673 |
} |
617 |
} |
674 |
} |
618 |
} |
675 |
|
619 |
|
676 |
TOKEN_GROUPS* ptg = NULL; |
620 |
return false; |
677 |
DWORD token_len = 0; |
|
|
678 |
|
679 |
while (true) |
680 |
{ |
681 |
/* Then we must query the size of the group information associated with |
682 |
the token. This is guarenteed to fail the first time through |
683 |
because there is no buffer. */ |
684 |
|
685 |
if (GetTokenInformation(tkhandle, |
686 |
TokenGroups, |
687 |
ptg, |
688 |
token_len, |
689 |
&token_len)) |
690 |
{ |
691 |
break; |
692 |
} |
693 |
|
694 |
/* If there had been a buffer, it's either too small or something |
695 |
else is wrong. Either way, we can dispose of it. */ |
696 |
|
697 |
if (ptg) |
698 |
{ |
699 |
gds__free(ptg); |
700 |
} |
701 |
|
702 |
/* Here we verify that GetTokenInformation failed for lack of a large |
703 |
enough buffer. */ |
704 |
|
705 |
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) |
706 |
{ |
707 |
CloseHandle(tkhandle); |
708 |
return false; |
709 |
} |
710 |
|
711 |
// Allocate a buffer for the group information. |
712 |
ptg = (TOKEN_GROUPS *) gds__alloc((SLONG) token_len); |
713 |
|
714 |
if (!ptg) |
715 |
{ |
716 |
CloseHandle(tkhandle); |
717 |
return false; /* NOMEM: */ |
718 |
} |
719 |
// FREE: earlier in this loop, and at procedure return |
720 |
} |
721 |
|
722 |
// Create a System Identifier for the Admin group. |
723 |
|
724 |
PSID admin_sid; |
725 |
|
726 |
if (!AllocateAndInitializeSid(&system_sid_authority, 2, |
727 |
SECURITY_BUILTIN_DOMAIN_RID, |
728 |
DOMAIN_ALIAS_RID_ADMINS, |
729 |
0, 0, 0, 0, 0, 0, &admin_sid)) |
730 |
{ |
731 |
gds__free(ptg); |
732 |
CloseHandle(tkhandle); |
733 |
return false; |
734 |
} |
735 |
|
736 |
// Finally we'll iterate through the list of groups for this access |
737 |
// token looking for a match against the SID we created above. |
738 |
|
739 |
bool admin_priv = false; |
740 |
|
741 |
for (DWORD i = 0; i < ptg->GroupCount; i++) |
742 |
{ |
743 |
if (EqualSid(ptg->Groups[i].Sid, admin_sid)) |
744 |
{ |
745 |
admin_priv = true; |
746 |
break; |
747 |
} |
748 |
} |
749 |
|
750 |
// Deallocate the SID we created. |
751 |
|
752 |
FreeSid(admin_sid); |
753 |
gds__free(ptg); |
754 |
CloseHandle(tkhandle); |
755 |
return admin_priv; |
756 |
} |
621 |
} |
757 |
#endif |
622 |
#endif |
758 |
|
623 |
|