r19287: As requested by Bjoern Jacke <bjoern@j3e.de>: Check in the NetBSD winbind...
authorVolker Lendecke <vlendec@samba.org>
Sun, 15 Oct 2006 08:32:25 +0000 (08:32 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:15:28 +0000 (12:15 -0500)
Mewburn.

Volker
(This used to be commit 104f5e9ec9aea71950308b8b73479f06bf3c66a2)

source3/configure.in
source3/nsswitch/winbind_nss.h
source3/nsswitch/winbind_nss_netbsd.c [new file with mode: 0644]
source3/nsswitch/winbind_nss_netbsd.h [new file with mode: 0644]

index 8531738ec0a23a36b17e2c0309c1facdb8db0225..d01dc43314f712159f9e6979734a63060bdd6fab 100644 (file)
@@ -1234,6 +1234,7 @@ AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate
 AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64)
 AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf)
 AC_CHECK_FUNCS(opendir64 readdir64 seekdir64 telldir64 rewinddir64 closedir64)
+AC_CHECK_FUNCS(getpwent_r)
 AC_CHECK_FUNCS(getdents getdents64)
 AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink)
 AC_CHECK_FUNCS(syslog vsyslog timegm)
@@ -5550,6 +5551,23 @@ case "$host_os" in
                WINBIND_NSS="nsswitch/nss_winbind.$SHLIBEXT"
                WINBIND_WINS_NSS="nsswitch/nss_wins.$SHLIBEXT"
                ;;
+
+       *netbsd*[[3-9]]*)
+               # NetBSD winbind client is implemented as a wrapper
+               # around the Linux version. It needs getpwent_r() to
+               # indicate libc's use of the correct nsdispatch API.
+               #
+               if test x"$ac_cv_func_getpwent_r" = x"yes"; then
+                       WINBIND_NSS_EXTRA_OBJS="\
+                           nsswitch/winbind_nss_netbsd.o \
+                           nsswitch/winbind_nss_linux.o"
+                       WINBIND_NSS="nsswitch/nss_winbind.$SHLIBEXT"
+                       WINBIND_WINS_NSS="nsswitch/nss_wins.$SHLIBEXT"
+               else
+                       HAVE_WINBIND=no
+                       winbind_no_reason=", getpwent_r is missing on $host_os so winbind is unsupported"
+               fi
+               ;;
        *irix*)
                # IRIX has differently named shared libraries
                WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o"
@@ -5613,6 +5631,11 @@ fi
 
 # Display test results
 
+if test x"$HAVE_WINBIND" = x"no"; then
+       WINBIND_NSS=""
+       WINBIND_WINS_NSS=""
+fi
+
 if test x"$HAVE_WINBIND" = x"yes"; then
         AC_MSG_RESULT(yes)
        AC_DEFINE(WITH_WINBIND,1,[Whether to build winbind])
index 5416ae211e3d479e5b15f96b5cf4f49fc1ff755a..3bef6ca59541b15e64f030d12b231a28cb66e031 100644 (file)
@@ -56,7 +56,15 @@ typedef enum nss_status NSS_STATUS;
 
 #include "nsswitch/winbind_nss_hpux.h"
 
-#else /* Nothing's defined. Neither gnu nor sun nor hp */
+#elif defined(__NetBSD__) && defined(HAVE_GETPWENT_R)
+
+/*
+ * NetBSD 3 and newer
+ */
+
+#include "nsswitch/winbind_nss_netbsd.h"
+
+#else /* Nothing's defined. Neither gnu nor netbsd nor sun nor hp */
 
 typedef enum
 {
diff --git a/source3/nsswitch/winbind_nss_netbsd.c b/source3/nsswitch/winbind_nss_netbsd.c
new file mode 100644 (file)
index 0000000..97eb0cc
--- /dev/null
@@ -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 Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 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 Library General Public
+   License along with this library; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA  02111-1307, USA.
+*/
+
+#include <sys/param.h>
+
+#include "winbind_client.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            agroup = va_arg(ap, gid_t);
+       gid_t           *groups = va_arg(ap, gid_t *);
+       int              maxgrp = va_arg(ap, int);
+       int             *groupc = va_arg(ap, int *);
+
+       struct winbindd_request request;
+       struct winbindd_response response;
+       gid_t   *wblistv;
+       int     wblistc, i, isdup, dupc;
+
+       ZERO_STRUCT(request);
+       ZERO_STRUCT(response);
+       strncpy(request.data.username, uname,
+                               sizeof(request.data.username) - 1);
+       i = winbindd_request_response(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 */
diff --git a/source3/nsswitch/winbind_nss_netbsd.h b/source3/nsswitch/winbind_nss_netbsd.h
new file mode 100644 (file)
index 0000000..e7f89bc
--- /dev/null
@@ -0,0 +1,42 @@
+/* 
+   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 Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 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 Library General Public
+   License along with this library; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA  02111-1307, USA.   
+*/
+
+#ifndef _WINBIND_NSS_NETBSD_H
+#define _WINBIND_NSS_NETBSD_H
+
+#include <nsswitch.h>
+
+       /* dynamic nsswitch with "new" getpw* nsdispatch API available */
+#if defined(NSS_MODULE_INTERFACE_VERSION) && defined(HAVE_GETPWENT_R)
+
+typedef int NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS     NS_SUCCESS
+#define NSS_STATUS_NOTFOUND    NS_NOTFOUND
+#define NSS_STATUS_UNAVAIL     NS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN    NS_TRYAGAIN
+
+#endif /* NSS_MODULE_INTERFACE_VERSION && HAVE_GETPWENT_R */
+
+#endif /* _WINBIND_NSS_NETBSD_H */