summaryrefslogtreecommitdiffstats
path: root/nsswitch/winbind_nss_netbsd.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
commit4f5791ebd03eaec1c7da0865a383175b05102712 (patch)
tree8ce7b00f7a76baa386372422adebbe64510812d4 /nsswitch/winbind_nss_netbsd.c
parentInitial commit. (diff)
downloadsamba-upstream.tar.xz
samba-upstream.zip
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'nsswitch/winbind_nss_netbsd.c')
-rw-r--r--nsswitch/winbind_nss_netbsd.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/nsswitch/winbind_nss_netbsd.c b/nsswitch/winbind_nss_netbsd.c
new file mode 100644
index 0000000..9455263
--- /dev/null
+++ b/nsswitch/winbind_nss_netbsd.c
@@ -0,0 +1,405 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ NetBSD loadable authentication module, providing identification
+ routines against Samba winbind/Windows NT Domain
+
+ Copyright (C) Luke Mewburn 2004-2005
+
+ 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 3 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
+ Library 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 <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "winbind_client.h"
+
+#include <sys/param.h>
+#include <stdarg.h>
+#include <syslog.h>
+
+ /* dynamic nsswitch with "new" getpw* nsdispatch API available */
+#if defined(NSS_MODULE_INTERFACE_VERSION) && defined(HAVE_GETPWENT_R)
+
+/*
+ group functions
+ ---------------
+*/
+
+static struct group _winbind_group;
+static char _winbind_groupbuf[1024];
+
+int
+netbsdwinbind_endgrent(void *nsrv, void *nscb, va_list ap)
+{
+ int rv;
+
+ rv = _nss_winbind_endgrent();
+ return rv;
+}
+
+int
+netbsdwinbind_setgrent(void *nsrv, void *nscb, va_list ap)
+{
+ int rv;
+
+ rv = _nss_winbind_setgrent();
+ return rv;
+}
+
+int
+netbsdwinbind_getgrent(void *nsrv, void *nscb, va_list ap)
+{
+ struct group **retval = va_arg(ap, struct group **);
+
+ int rv, rerrno;
+
+ *retval = NULL;
+ rv = _nss_winbind_getgrent_r(&_winbind_group,
+ _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
+ if (rv == NS_SUCCESS)
+ *retval = &_winbind_group;
+ return rv;
+}
+
+int
+netbsdwinbind_getgrent_r(void *nsrv, void *nscb, va_list ap)
+{
+ int *retval = va_arg(ap, int *);
+ struct group *grp = va_arg(ap, struct group *);
+ char *buffer = va_arg(ap, char *);
+ size_t buflen = va_arg(ap, size_t);
+ struct group **result = va_arg(ap, struct group **);
+
+ int rv, rerrno;
+
+ *result = NULL;
+ rerrno = 0;
+
+ rv = _nss_winbind_getgrent_r(grp, buffer, buflen, &rerrno);
+ if (rv == NS_SUCCESS)
+ *result = grp;
+ else
+ *retval = rerrno;
+ return rv;
+}
+
+int
+netbsdwinbind_getgrgid(void *nsrv, void *nscb, va_list ap)
+{
+ struct group **retval = va_arg(ap, struct group **);
+ gid_t gid = va_arg(ap, gid_t);
+
+ int rv, rerrno;
+
+ *retval = NULL;
+ rv = _nss_winbind_getgrgid_r(gid, &_winbind_group,
+ _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
+ if (rv == NS_SUCCESS)
+ *retval = &_winbind_group;
+ return rv;
+}
+
+int
+netbsdwinbind_getgrgid_r(void *nsrv, void *nscb, va_list ap)
+{
+ int *retval = va_arg(ap, int *);
+ gid_t gid = va_arg(ap, gid_t);
+ struct group *grp = va_arg(ap, struct group *);
+ char *buffer = va_arg(ap, char *);
+ size_t buflen = va_arg(ap, size_t);
+ struct group **result = va_arg(ap, struct group **);
+
+ int rv, rerrno;
+
+ *result = NULL;
+ rerrno = 0;
+
+ rv = _nss_winbind_getgrgid_r(gid, grp, buffer, buflen, &rerrno);
+ if (rv == NS_SUCCESS)
+ *result = grp;
+ else
+ *retval = rerrno;
+ return rv;
+}
+
+int
+netbsdwinbind_getgrnam(void *nsrv, void *nscb, va_list ap)
+{
+ struct group **retval = va_arg(ap, struct group **);
+ const char *name = va_arg(ap, const char *);
+
+ int rv, rerrno;
+
+ *retval = NULL;
+ rv = _nss_winbind_getgrnam_r(name, &_winbind_group,
+ _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
+ if (rv == NS_SUCCESS)
+ *retval = &_winbind_group;
+ return rv;
+}
+
+int
+netbsdwinbind_getgrnam_r(void *nsrv, void *nscb, va_list ap)
+{
+ int *retval = va_arg(ap, int *);
+ const char *name = va_arg(ap, const char *);
+ struct group *grp = va_arg(ap, struct group *);
+ char *buffer = va_arg(ap, char *);
+ size_t buflen = va_arg(ap, size_t);
+ struct group **result = va_arg(ap, struct group **);
+
+ int rv, rerrno;
+
+ *result = NULL;
+ rerrno = 0;
+
+ rv = _nss_winbind_getgrnam_r(name, grp, buffer, buflen, &rerrno);
+ if (rv == NS_SUCCESS)
+ *result = grp;
+ else
+ *retval = rerrno;
+ return rv;
+}
+
+int
+netbsdwinbind_getgroupmembership(void *nsrv, void *nscb, va_list ap)
+{
+ int *result = va_arg(ap, int *);
+ const char *uname = va_arg(ap, const char *);
+ gid_t *groups = va_arg(ap, gid_t *);
+ int maxgrp = va_arg(ap, int);
+ int *groupc = va_arg(ap, int *);
+
+ struct winbindd_request request = {
+ .wb_flags = WBFLAG_FROM_NSS,
+ };
+ struct winbindd_response response = {
+ .length = 0,
+ }
+ gid_t *wblistv;
+ int wblistc, i, isdup, dupc;
+
+ strncpy(request.data.username, uname,
+ sizeof(request.data.username) - 1);
+ i = winbindd_request_response(NULL, WINBINDD_GETGROUPS,
+ &request, &response);
+ if (i != NSS_STATUS_SUCCESS)
+ return NS_NOTFOUND;
+ wblistv = (gid_t *)response.extra_data.data;
+ wblistc = response.data.num_entries;
+
+ for (i = 0; i < wblistc; i++) { /* add winbind gids */
+ isdup = 0; /* skip duplicates */
+ for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++) {
+ if (groups[dupc] == wblistv[i]) {
+ isdup = 1;
+ break;
+ }
+ }
+ if (isdup)
+ continue;
+ if (*groupc < maxgrp) /* add this gid */
+ groups[*groupc] = wblistv[i];
+ else
+ *result = -1;
+ (*groupc)++;
+ }
+ SAFE_FREE(wblistv);
+ return NS_NOTFOUND;
+}
+
+
+/*
+ passwd functions
+ ----------------
+*/
+
+static struct passwd _winbind_passwd;
+static char _winbind_passwdbuf[1024];
+
+int
+netbsdwinbind_endpwent(void *nsrv, void *nscb, va_list ap)
+{
+ int rv;
+
+ rv = _nss_winbind_endpwent();
+ return rv;
+}
+
+int
+netbsdwinbind_setpwent(void *nsrv, void *nscb, va_list ap)
+{
+ int rv;
+
+ rv = _nss_winbind_setpwent();
+ return rv;
+}
+
+int
+netbsdwinbind_getpwent(void *nsrv, void *nscb, va_list ap)
+{
+ struct passwd **retval = va_arg(ap, struct passwd **);
+
+ int rv, rerrno;
+
+ *retval = NULL;
+
+ rv = _nss_winbind_getpwent_r(&_winbind_passwd,
+ _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
+ if (rv == NS_SUCCESS)
+ *retval = &_winbind_passwd;
+ return rv;
+}
+
+int
+netbsdwinbind_getpwent_r(void *nsrv, void *nscb, va_list ap)
+{
+ int *retval = va_arg(ap, int *);
+ struct passwd *pw = va_arg(ap, struct passwd *);
+ char *buffer = va_arg(ap, char *);
+ size_t buflen = va_arg(ap, size_t);
+ struct passwd **result = va_arg(ap, struct passwd **);
+
+ int rv, rerrno;
+
+ *result = NULL;
+ rerrno = 0;
+
+ rv = _nss_winbind_getpwent_r(pw, buffer, buflen, &rerrno);
+ if (rv == NS_SUCCESS)
+ *result = pw;
+ else
+ *retval = rerrno;
+ return rv;
+}
+
+int
+netbsdwinbind_getpwnam(void *nsrv, void *nscb, va_list ap)
+{
+ struct passwd **retval = va_arg(ap, struct passwd **);
+ const char *name = va_arg(ap, const char *);
+
+ int rv, rerrno;
+
+ *retval = NULL;
+ rv = _nss_winbind_getpwnam_r(name, &_winbind_passwd,
+ _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
+ if (rv == NS_SUCCESS)
+ *retval = &_winbind_passwd;
+ return rv;
+}
+
+int
+netbsdwinbind_getpwnam_r(void *nsrv, void *nscb, va_list ap)
+{
+ int *retval = va_arg(ap, int *);
+ const char *name = va_arg(ap, const char *);
+ struct passwd *pw = va_arg(ap, struct passwd *);
+ char *buffer = va_arg(ap, char *);
+ size_t buflen = va_arg(ap, size_t);
+ struct passwd **result = va_arg(ap, struct passwd **);
+
+ int rv, rerrno;
+
+ *result = NULL;
+ rerrno = 0;
+
+ rv = _nss_winbind_getpwnam_r(name, pw, buffer, buflen, &rerrno);
+ if (rv == NS_SUCCESS)
+ *result = pw;
+ else
+ *retval = rerrno;
+ return rv;
+}
+
+int
+netbsdwinbind_getpwuid(void *nsrv, void *nscb, va_list ap)
+{
+ struct passwd **retval = va_arg(ap, struct passwd **);
+ uid_t uid = va_arg(ap, uid_t);
+
+ int rv, rerrno;
+
+ *retval = NULL;
+ rv = _nss_winbind_getpwuid_r(uid, &_winbind_passwd,
+ _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
+ if (rv == NS_SUCCESS)
+ *retval = &_winbind_passwd;
+ return rv;
+}
+
+int
+netbsdwinbind_getpwuid_r(void *nsrv, void *nscb, va_list ap)
+{
+ int *retval = va_arg(ap, int *);
+ uid_t uid = va_arg(ap, uid_t);
+ struct passwd *pw = va_arg(ap, struct passwd *);
+ char *buffer = va_arg(ap, char *);
+ size_t buflen = va_arg(ap, size_t);
+ struct passwd **result = va_arg(ap, struct passwd **);
+
+ int rv, rerrno;
+
+ *result = NULL;
+ rerrno = 0;
+
+ rv = _nss_winbind_getpwuid_r(uid, pw, buffer, buflen, &rerrno);
+ if (rv == NS_SUCCESS)
+ *result = pw;
+ else
+ *retval = rerrno;
+ return rv;
+}
+
+
+/*
+ nsswitch module setup
+ ---------------------
+*/
+
+
+static ns_mtab winbind_methods[] = {
+
+{ NSDB_GROUP, "endgrent", netbsdwinbind_endgrent, NULL },
+{ NSDB_GROUP, "getgrent", netbsdwinbind_getgrent, NULL },
+{ NSDB_GROUP, "getgrent_r", netbsdwinbind_getgrent_r, NULL },
+{ NSDB_GROUP, "getgrgid", netbsdwinbind_getgrgid, NULL },
+{ NSDB_GROUP, "getgrgid_r", netbsdwinbind_getgrgid_r, NULL },
+{ NSDB_GROUP, "getgrnam", netbsdwinbind_getgrnam, NULL },
+{ NSDB_GROUP, "getgrnam_r", netbsdwinbind_getgrnam_r, NULL },
+{ NSDB_GROUP, "setgrent", netbsdwinbind_setgrent, NULL },
+{ NSDB_GROUP, "setgroupent", netbsdwinbind_setgrent, NULL },
+{ NSDB_GROUP, "getgroupmembership", netbsdwinbind_getgroupmembership, NULL },
+
+{ NSDB_PASSWD, "endpwent", netbsdwinbind_endpwent, NULL },
+{ NSDB_PASSWD, "getpwent", netbsdwinbind_getpwent, NULL },
+{ NSDB_PASSWD, "getpwent_r", netbsdwinbind_getpwent_r, NULL },
+{ NSDB_PASSWD, "getpwnam", netbsdwinbind_getpwnam, NULL },
+{ NSDB_PASSWD, "getpwnam_r", netbsdwinbind_getpwnam_r, NULL },
+{ NSDB_PASSWD, "getpwuid", netbsdwinbind_getpwuid, NULL },
+{ NSDB_PASSWD, "getpwuid_r", netbsdwinbind_getpwuid_r, NULL },
+{ NSDB_PASSWD, "setpassent", netbsdwinbind_setpwent, NULL },
+{ NSDB_PASSWD, "setpwent", netbsdwinbind_setpwent, NULL },
+
+};
+
+ns_mtab *
+nss_module_register(const char *source, unsigned int *mtabsize,
+ nss_module_unregister_fn *unreg)
+{
+ *mtabsize = sizeof(winbind_methods)/sizeof(winbind_methods[0]);
+ *unreg = NULL;
+ return (winbind_methods);
+}
+
+#endif /* NSS_MODULE_INTERFACE_VERSION && HAVE_GETPWENT_R */