From 7675d041262bb65672877e62e0e438d28dc7dc87 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 9 Aug 2016 15:15:12 +0200 Subject: [PATCH 2/2] intg: Allow to test netgroups sh-4.2# getent netgroup -s sss QAUsers QAUsers ( ,qa1,example.com) ( ,qa2,example.com) ( ,qa3,example.com) sh-4.2# getent netgroup -s sss QASystems QASystems (qahost1.example.com,,) (qahost2.lab.eng.pnq.redhat.com,,) sh-4.2# getent netgroup -s sss test sh-4.2# echo $? 2 sh-4.2# python Python 2.7.5 (default, Aug 2 2016, 04:20:16) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sssd_netgroup >>> sssd_netgroup.get_sssd_netgroups('QAUsers') (1, 0, [(None, 'qa1', 'example.com'), (None, 'qa2', 'example.com'), (None, 'qa3', 'example.com')]) >>> sssd_netgroup.get_sssd_netgroups('QASystems') (1, 0, [('qahost1.example.com', None, None), ('qahost2.lab.eng.pnq.redhat.com', None, None)]) >>> sssd_netgroup.get_sssd_netgroups('test') (0, 0, []) >>> --- src/tests/intg/Makefile.am | 1 + src/tests/intg/sssd_netgroup.py | 155 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 src/tests/intg/sssd_netgroup.py diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am index d79f6424e0226f8b81d3a104877fa166bd885b42..b8cc5c006845f911d8518df815925455482e9f6d 100644 --- a/src/tests/intg/Makefile.am +++ b/src/tests/intg/Makefile.am @@ -2,6 +2,7 @@ dist_noinst_DATA = \ config.py.m4 \ sssd_id.py \ sssd_ldb.py \ + sssd_netgroup.py \ ds.py \ ds_openldap.py \ ent.py \ diff --git a/src/tests/intg/sssd_netgroup.py b/src/tests/intg/sssd_netgroup.py new file mode 100644 index 0000000000000000000000000000000000000000..9f3e5204ef5b935ffdf3b3fc998e5592be3100c3 --- /dev/null +++ b/src/tests/intg/sssd_netgroup.py @@ -0,0 +1,155 @@ +# +# Module for simulation of utility "getent netgroup -s sss" from coreutils +# +# Copyright (c) 2016 Red Hat, Inc. +# Author: Lukas Slebodnik +# +# This is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 only +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +from ctypes import (cdll, c_int, c_char, c_char_p, c_size_t, c_void_p, c_ulong, + POINTER, Structure, Union, create_string_buffer, get_errno) +import config + + +class NetgroupType(object): + """ 'enum' class for type of netgroup """ + TRIPLE_VAL = 0 + GROUP_VAL = 1 + + +class Triple(Structure): + _fields_ = [("host", c_char_p), + ("user", c_char_p), + ("domain", c_char_p)] + + +class Val(Union): + _fields_ = [("triple", Triple), + ("group", c_char_p)] + + +class Idx(Union): + _fields_ = [("cursor", POINTER(c_char)), + ("position", c_ulong)] + + +class NameList(Structure): + pass + +NameList._fields_ = [("next", POINTER(NameList)), + ("name", POINTER(c_char))] + + +class NssReturnCode(object): + """ 'enum' class for name service switch return code """ + TRYAGAIN = -2, + UNAVAIL = -1 + NOTFOUND = 0 + SUCCESS = 1 + RETURN = 2 + + +class Netgrent(Structure): + _fields_ = [("type", c_int), + ("val", Val), + ("data", POINTER(c_char)), + ("data_size", c_size_t), + ("idx", Idx), + ("first", c_int), + ("known_groups", POINTER(NameList)), + ("needed_groups", POINTER(NameList)), + ("nip", c_void_p)] + + +def call_sssd_setnetgrent(netgroup): + libnss_sss_path = config.NSS_MODULE_DIR + "/libnss_sss.so.2" + libnss_sss = cdll.LoadLibrary(libnss_sss_path) + + func = libnss_sss._nss_sss_setnetgrent + func.restype = c_int + func.argtypes = [c_char_p, POINTER(Netgrent)] + + result = Netgrent() + result_p = POINTER(Netgrent)(result) + + res = func(c_char_p(netgroup), result_p) + + return (int(res), result_p) + + +def call_sssd_getnetgrent_r(result_p, buff, buff_len): + libnss_sss_path = config.NSS_MODULE_DIR + "/libnss_sss.so.2" + libnss_sss = cdll.LoadLibrary(libnss_sss_path) + + func = libnss_sss._nss_sss_getnetgrent_r + func.restype = c_int + func.argtypes = [POINTER(Netgrent), POINTER(c_char), c_size_t, + POINTER(c_int)] + + errno = POINTER(c_int)(c_int(0)) + + res = func(result_p, buff, buff_len, errno) + + return (int(res), int(errno[0]), result_p) + + +def call_sssd_endnetgrent(result_p): + libnss_sss_path = config.NSS_MODULE_DIR + "/libnss_sss.so.2" + libnss_sss = cdll.LoadLibrary(libnss_sss_path) + + func = libnss_sss._nss_sss_endnetgrent + func.restype = c_int + func.argtypes = [POINTER(Netgrent)] + + res = func(result_p) + + return int(res) + + +def get_sssd_netgroups(name): + """ + Function will return netgroup triplets for given user. It will gather + netgroups only provided by sssd. + The equivalent of "getent netgroup -s sss user" + + @param string name name of netgroup + + @return (int, int, List[(string, string, string]) (err, errno, netgroups) + if err is NssReturnCode.SUCCESS netgroups will contain list of touples. + Each touple will consist of 3 elemets either string or None + (host, user, domain). + """ + buff_len = 1024 * 1024 + buff = create_string_buffer(buff_len) + + result = [] + + res, result_p = call_sssd_setnetgrent(name) + if res != NssReturnCode.SUCCESS: + return (res, get_errno(), result) + + res, errno, result_p = call_sssd_getnetgrent_r(result_p, buff, buff_len) + while res == NssReturnCode.SUCCESS: + assert result_p[0].type == NetgroupType.TRIPLE_VAL + result.append((result_p[0].val.triple.host, + result_p[0].val.triple.user, + result_p[0].val.triple.domain)) + res, errno, result_p = call_sssd_getnetgrent_r(result_p, buff, + buff_len) + + if res != NssReturnCode.RETURN: + return (res, errno, result) + + res = call_sssd_endnetgrent(result_p) + + return (res, errno, result) -- 2.9.2