diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a5e3791 --- /dev/null +++ b/Makefile @@ -0,0 +1,142 @@ +NAME ?= sailfishaccesscontrol +ROOT ?= /tmp/test-$(NAME) + +PREFIX ?= /usr +LIBDIR ?= $(PREFIX)/lib +INCDIR ?= $(PREFIX)/include/$(NAME) + +PKGCFGDIR ?= $(PREFIX)/lib/pkgconfig + +SO ?= .so.0 + +TEMPLATE_COPY = sed\ + -e 's:@NAME@:${NAME}:g'\ + -e 's:@VERSION@:${VERSION}:g'\ + -e 's:@ROOT@:${ROOT}:g'\ + -e 's:@PREFIX@:${PREFIX}:g'\ + -e 's:@LIBDIR@:${LIBDIR}:g'\ + -e 's:@INCDIR@:${INCDIR}:g'\ + -e 's:@DOCDIR@:${DOCDIR}:g'\ + -e 's:@MANDIR@:${MANDIR}:g'\ + -e 's:@PKGCFGDIR@:${PKGCFGDIR}:g'\ + < $< > $@ + +# ---------------------------------------------------------------------------- +# Global Flags +# ---------------------------------------------------------------------------- + +CPPFLAGS += -D_GNU_SOURCE + +CFLAGS += -Wall +CFLAGS += -Wmissing-prototypes +CFLAGS += -Wunused-result +CFLAGS += -W +CFLAGS += -std=c99 +CFLAGS += -O2 +CFLAGS += -fPIC +CFLAGS += -g + +LDFLAGS += -fPIC + +LDFLAGS += -g +LDLIBS += -Wl,--as-needed +# flags from pkgtool + +PKG_NAMES := glib-2.0 +PKG_CFLAGS := $(shell pkg-config --cflags $(PKG_NAMES)) +PKG_LDLIBS := $(shell pkg-config --libs $(PKG_NAMES)) + +CFLAGS += $(PKG_CFLAGS) +LDLIBS += $(PKG_LDLIBS) + +# ---------------------------------------------------------------------------- +# Top Level Targets +# ---------------------------------------------------------------------------- + +TARGETS += lib$(NAME)$(SO) + +.PHONY: build clean distclean mostlyclean install + +build:: $(TARGETS) + +extra:: $(EXTRA) + +all:: build extra + +clean:: mostlyclean + $(RM) $(TARGETS) $(EXTRA) + +distclean:: clean + +mostlyclean:: + $(RM) *.o *~ + +install:: $(addprefix install-,libsailfishaccesscontrol libsailfishaccesscontrol-dev) + +# ---------------------------------------------------------------------------- +# Pattern rules +# ---------------------------------------------------------------------------- + +install-%-lib: + $(if $<, install -m755 -d $(ROOT)$(LIBDIR)) + $(if $<, install -m755 $^ $(ROOT)$(LIBDIR)) + +install-%-inc: + $(if $<, install -m755 -d $(ROOT)$(INCDIR)) + $(if $<, install -m644 $^ $(ROOT)$(INCDIR)) + +%.pc : %.pc.tpl ; $(TEMPLATE_COPY) +% : %.tpl ; $(TEMPLATE_COPY) + +% : %.o + $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(CFLAGS) + +%$(SO): LDFLAGS += -shared -Wl,-soname,$@ + +%$(SO): + $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(CFLAGS) + +%.a: + $(AR) r $@ $^ + +%.pic.o : CFLAGS += -fPIC +%.pic.o : CFLAGS += -fvisibility=hidden + +%.pic.o : %.c + @echo "Compile Dynamic: $<" + @$(CC) -o $@ -c $< $(CPPFLAGS) $(CFLAGS) + +%.o : %.c + @echo "Compile Static: $<" + @$(CC) -o $@ -c $< $(CPPFLAGS) $(CFLAGS) + +# ---------------------------------------------------------------------------- +# libsailfishaccesscontrol +# ---------------------------------------------------------------------------- + +lib$(NAME)_src =\ + sailfishaccesscontrol.c + +lib$(NAME)_obj = $(libsailfishaccesscontrol_src:.c=.o) + +lib$(NAME)$(SO) : $(libsailfishaccesscontrol_obj:.o=.pic.o) + +install-lib$(NAME)-dll: lib$(NAME)$(SO) +install-lib$(NAME):: $(addprefix install-lib$(NAME)-, dll) + mkdir -p $(ROOT)$(LIBDIR)/ + install -m755 lib$(NAME)$(SO) $(ROOT)$(LIBDIR)/ + +# ---------------------------------------------------------------------------- +# libsailfishaccesscontrol-dev +# ---------------------------------------------------------------------------- + +install-libsailfishaccesscontrol-dev-inc: sailfishaccesscontrol.h +install-libsailfishaccesscontrol-dev-lib: libsailfishaccesscontrol.a + +install-libsailfishaccesscontrol-dev:: $(addprefix install-libsailfishaccesscontrol-dev-, lib inc) $(NAME).pc + ln -sf lib$(NAME)$(SO) $(ROOT)$(LIBDIR)/lib$(NAME).so + install -m755 -d $(ROOT)$(PKGCFGDIR) + install -m644 $(NAME).pc $(ROOT)$(PKGCFGDIR)/ + +clean:: + $(RM) $(NAME).pc diff --git a/rpm/sailfish-access-control.spec b/rpm/sailfish-access-control.spec new file mode 100644 index 0000000..3e42b47 --- /dev/null +++ b/rpm/sailfish-access-control.spec @@ -0,0 +1,53 @@ +Name: sailfish-access-control +Summary: Sailfish Access Control library +Version: 0.0.1 +Release: 1 +License: LGPLv2+ +URL: https://git.sailfishos.org/mer-core/sailfish-access-control +Source0: %{name}-%{version}.tar.bz2 +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +Requires: glibc +BuildRequires: glibc-devel +BuildRequires: pkgconfig(glib-2.0) + +%description +Sailfish Access Control library is a thin wrapper on top +of pwd.h and grp.h of glibc. + +This library should be used to check whether a user +belongs to a group or not. + +%package devel +Summary: Development files for Sailfish Access Control +Requires: %{name} = %{version}-%{release} + +%description devel +C language headers of the Sailfish Access Control library. + +%prep +%setup -q -n %{name}-%{version} + +%build +make ROOT=%{buildroot} %{_smp_mflags} VERSION=%{version} +make ROOT=%{buildroot} VERSION=%{version} sailfishaccesscontrol.pc + +%install +rm -rf %{buildroot} + +make ROOT=%{buildroot} install-libsailfishaccesscontrol +make ROOT=%{buildroot} install-libsailfishaccesscontrol-dev + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%{_libdir}/libsailfishaccesscontrol.so.* + +%files devel +%defattr(-,root,root,-) +%{_includedir}/sailfishaccesscontrol/* +%{_libdir}/libsailfishaccesscontrol.so +%{_libdir}/pkgconfig/sailfishaccesscontrol.pc diff --git a/sailfish-access-control.pro b/sailfish-access-control.pro new file mode 100644 index 0000000..c45b3f2 --- /dev/null +++ b/sailfish-access-control.pro @@ -0,0 +1,10 @@ +# For QtCreator integration purposes. Not meant for building the project. +TEMPLATE = aux + +HEADERS += sailfishaccesscontrol.h +SOURCES += sailfishaccesscontrol.c + +OTHER_FILES += \ + Makefile \ + sailfishaccesscontrol.pc.tpl \ + rpm/sailfish-access-control.spec \ diff --git a/sailfishaccesscontrol.c b/sailfishaccesscontrol.c new file mode 100644 index 0000000..18f3f9b --- /dev/null +++ b/sailfishaccesscontrol.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2019 Open Mobile Platform LLC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#include "sailfishaccesscontrol.h" + +#include +#include +#include +#include + +#define NO_GROUPS GINT_TO_POINTER(1) + +GHashTable *s_groups = NULL; + +static GSList *init_group_list(uid_t uid) +{ + GSList *group_list = NULL; + struct passwd *passwd_entry = getpwuid(uid); + + if (passwd_entry) { + int ngroups = 32; + const char *user_name = passwd_entry->pw_name; + gid_t group_id = passwd_entry->pw_gid; + gid_t *groups = g_malloc0(ngroups * sizeof(gid_t)); + + if (getgrouplist(user_name, group_id, groups, &ngroups) == -1) { + g_free(groups); + // When failing ngroups will contain number of groups. + groups = g_malloc0(ngroups * sizeof(gid_t)); + if (getgrouplist(user_name, group_id, groups, &ngroups) == -1) + ngroups = 0; + } + + for (int i = 0; i < ngroups; i++) { + struct group *gr = getgrgid(groups[i]); + if (gr) + group_list = g_slist_prepend(group_list, g_strdup(gr->gr_name)); + } + + g_free(groups); + } + g_hash_table_insert(s_groups, GINT_TO_POINTER(uid), (group_list ? group_list : NO_GROUPS)); + return group_list; +} + +bool sailfish_access_control_hasgroup(uid_t uid, const char *group_name) +{ + GSList *groups = NULL; + if (!s_groups) + s_groups = g_hash_table_new(NULL, NULL); + + groups = g_hash_table_lookup(s_groups, GINT_TO_POINTER(uid)); + if (!groups) + groups = init_group_list(uid); + + if (groups == NO_GROUPS) + return false; + + GSList *item = g_slist_find_custom(groups, group_name, (GCompareFunc)g_strcmp0); + if (item) + return true; + + return false; +} diff --git a/sailfishaccesscontrol.h b/sailfishaccesscontrol.h new file mode 100644 index 0000000..1a62160 --- /dev/null +++ b/sailfishaccesscontrol.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 Open Mobile Platform LLC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#ifndef SAILFISH_ACCESS_CONTROL_H_ +#define SAILFISH_ACCESS_CONTROL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +#pragma GCC visibility push(default) + +bool sailfish_access_control_hasgroup(uid_t uid, const char *group_name); + +#pragma GCC visibility pop + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/sailfishaccesscontrol.pc.tpl b/sailfishaccesscontrol.pc.tpl new file mode 100644 index 0000000..ee5b7ce --- /dev/null +++ b/sailfishaccesscontrol.pc.tpl @@ -0,0 +1,11 @@ +prefix=@PREFIX@ +libdir=@LIBDIR@ +includedir=@INCDIR@ + +Name: Sailfish Access Control +Description: Sailfish Access Control library +Version: @VERSION@ +Requires: glib-2.0 +Requires.private: +Cflags: -I@INCDIR@ +Libs: -L@LIBDIR@ -lsailfishaccesscontrol