aboutsummaryrefslogtreecommitdiff
path: root/src/util/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/service.c')
-rw-r--r--src/util/service.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/src/util/service.c b/src/util/service.c
index 8235830c9..243e7daa9 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -501,14 +501,18 @@ struct GNUNET_SERVICE_Context
501 int require_found; 501 int require_found;
502 502
503 /** 503 /**
504 * Do we require a matching UID for UNIX domain socket 504 * Do we require a matching UID for UNIX domain socket connections?
505 * connections? 505 * GNUNET_NO means that the UID does not have to match (however,
506 * "match_gid" may still impose other access control checks).
506 */ 507 */
507 int match_uid; 508 int match_uid;
508 509
509 /** 510 /**
510 * Do we require a matching GID for UNIX domain socket 511 * Do we require a matching GID for UNIX domain socket connections?
511 * connections? 512 * Ignored if "match_uid" is GNUNET_YES. Note that this is about
513 * checking that the client's UID is in our group OR that the
514 * client's GID is our GID. If both "match_gid" and "match_uid" are
515 * "GNUNET_NO", all users on the local system have access.
512 */ 516 */
513 int match_gid; 517 int match_gid;
514 518
@@ -617,15 +621,50 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
617#ifndef WINDOWS 621#ifndef WINDOWS
618 case AF_UNIX: 622 case AF_UNIX:
619 ret = GNUNET_OK; /* always OK for now */ 623 ret = GNUNET_OK; /* always OK for now */
620 if ((sctx->match_uid == GNUNET_YES) || (sctx->match_gid == GNUNET_YES)) 624 if (sctx->match_uid == GNUNET_YES)
621 ret = GNUNET_NO; 625 {
622 if ((uc != NULL) && 626 /* UID match required */
623 ((sctx->match_uid != GNUNET_YES) || (uc->uid == geteuid ()) || 627 ret = (uc != NULL) && (uc->uid == geteuid ());
624 (uc->uid == getuid ())) && ((sctx->match_gid != GNUNET_YES) || 628 }
625 (uc->gid == getegid ()) || 629 else if (sctx->match_gid == GNUNET_YES)
626 (uc->gid == getgid ()))) 630 {
627 ret = GNUNET_YES; 631 /* group match required */
628 else 632 if (uc == NULL)
633 {
634 /* no credentials, group match not possible */
635 ret = GNUNET_NO;
636 }
637 else
638 {
639 struct group *grp;
640 unsigned int i;
641
642 if (uc->gid != getegid())
643 {
644 /* default group did not match, but maybe the user is in our group, let's check */
645 grp = getgrgid (getegid ());
646 if (NULL == grp)
647 {
648 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getgrgid");
649 return GNUNET_NO;
650 }
651 ret = GNUNET_NO;
652 for (i=0; NULL != grp->gr_mem[i]; i++)
653 {
654 struct passwd *nam = getpwnam (grp->gr_mem[i]);
655 if (NULL == nam)
656 continue; /* name in group that is not in user DB !? */
657 if (nam->pw_uid == uc->uid)
658 {
659 /* yes, uid is in our group, allow! */
660 ret = GNUNET_YES;
661 break;
662 }
663 }
664 }
665 }
666 }
667 if (GNUNET_NO == ret)
629 LOG (GNUNET_ERROR_TYPE_WARNING, _("Access denied to UID %d / GID %d\n"), 668 LOG (GNUNET_ERROR_TYPE_WARNING, _("Access denied to UID %d / GID %d\n"),
630 (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid); 669 (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid);
631 break; 670 break;