dnl
dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
dnl
-dnl $Id: configure.in,v 1.269 2002/05/19 15:07:55 hno Exp $
+dnl $Id: configure.in,v 1.270 2002/05/19 23:42:39 hno Exp $
dnl
dnl
dnl
AC_INIT(src/main.c)
AC_CONFIG_AUX_DIR(cfgaux)
-AM_INIT_AUTOMAKE(squid, 2.6-DEVEL)
+AM_INIT_AUTOMAKE(Squid, 2.6-DEVEL)
AM_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.269 $)dnl
+AC_REVISION($Revision: 1.270 $)dnl
AC_PREFIX_DEFAULT(/usr/local/squid)
AM_MAINTAINER_MODE
src/auth/ntlm/helpers/no_check/Makefile \
src/auth/ntlm/helpers/SMB/Makefile \
src/auth/ntlm/helpers/SMB/smbval/Makefile \
+ src/auth/ntlm/helpers/winbind/Makefile \
contrib/Makefile \
snmplib/Makefile \
icons/Makefile \
--- /dev/null
+#
+# Makefile for the Squid Object Cache server
+#
+# $Id: Makefile.am,v 1.1 2002/05/19 23:42:40 hno Exp $
+#
+
+libexec_PROGRAMS = wb_auth
+wb_auth_SOURCES = wb_basic_auth.c wb_common.c
+INCLUDES = -I. -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src
+LDADD = -L$(top_builddir)/lib -lmiscutil -lntlmauth
--- /dev/null
+#ifndef _NSSWITCH_NSS_H
+#define _NSSWITCH_NSS_H
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+
+ a common place to work out how to define NSS_STATUS on various
+ platforms
+
+ Copyright (C) Tim Potter 2000
+
+ 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.
+*/
+
+#ifdef HAVE_NSS_COMMON_H
+
+/* Sun Solaris */
+
+#include <nss_common.h>
+#include <nss_dbdefs.h>
+#include <nsswitch.h>
+
+typedef nss_status_t NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS NSS_SUCCESS
+#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+
+#elif HAVE_NSS_H
+
+/* GNU */
+
+#include <nss.h>
+
+typedef enum nss_status NSS_STATUS;
+
+#elif HAVE_NS_API_H
+
+/* SGI IRIX */
+
+/* following required to prevent warnings of double definition
+ * of datum from ns_api.h
+*/
+#ifdef DATUM
+#define _DATUM_DEFINED
+#endif
+
+#include <ns_api.h>
+
+typedef enum
+{
+ NSS_STATUS_SUCCESS=NS_SUCCESS,
+ NSS_STATUS_NOTFOUND=NS_NOTFOUND,
+ NSS_STATUS_UNAVAIL=NS_UNAVAIL,
+ NSS_STATUS_TRYAGAIN=NS_TRYAGAIN
+} NSS_STATUS;
+
+#define NSD_MEM_STATIC 0
+#define NSD_MEM_VOLATILE 1
+#define NSD_MEM_DYNAMIC 2
+
+#elif defined(HPUX)
+/* HP-UX 11 */
+
+#include "nsswitch/hp_nss_common.h"
+#include "nsswitch/hp_nss_dbdefs.h"
+#include <nsswitch.h>
+
+#ifndef _HAVE_TYPEDEF_NSS_STATUS
+#define _HAVE_TYPEDEF_NSS_STATUS
+typedef nss_status_t NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS NSS_SUCCESS
+#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+#endif /* HPUX */
+
+#else /* Nothing's defined. Neither gnu nor sun nor hp */
+
+typedef enum
+{
+ NSS_STATUS_SUCCESS=0,
+ NSS_STATUS_NOTFOUND=1,
+ NSS_STATUS_UNAVAIL=2,
+ NSS_STATUS_TRYAGAIN=3
+} NSS_STATUS;
+
+#endif
+
+#endif /* _NSSWITCH_NSS_H */
--- /dev/null
+/*
+ * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
+ *
+ * Distributed freely under the terms of the GNU General Public License,
+ * version 2. See the file COPYING for licensing details
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+
+#include "wbntlm.h"
+#include "util.h"
+/* stdio.h is included in wbntlm.h */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/time.h> /* for gettimeofday */
+#include <errno.h> /* BUG: is this portable? */
+
+#include "winbind_nss_config.h"
+#include "winbindd_nss.h"
+
+char debug_enabled=1;
+char *myname;
+pid_t mypid;
+
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+
+
+void do_authenticate(char *user, char *pass) {
+ struct winbindd_request request;
+ struct winbindd_response response;
+ NSS_STATUS winbindd_result;
+
+ memset(&request,0,sizeof(struct winbindd_request));
+ memset(&response,0,sizeof(struct winbindd_response));
+
+
+ strncpy(request.data.auth.user,user,sizeof(fstring)-1);
+ strncpy(request.data.auth.pass,pass,sizeof(fstring)-1);
+
+ winbindd_result = winbindd_request(WINBINDD_PAM_AUTH,
+ &request, &response);
+ debug("winbindd result: %d\n",winbindd_result);
+
+ if (winbindd_result==WINBINDD_OK) {
+ SEND("OK");
+ } else {
+ SEND("ERR");
+ }
+
+ return; /* useless */
+}
+
+void manage_request(void) {
+ char buf[BUFFER_SIZE+1];
+ int length;
+ char *c, *user, *pass;
+
+ if (fgets(buf, BUFFER_SIZE, stdin) == NULL) {
+ warn("fgets() failed! dying..... errno=%d (%s)\n", errno,
+ strerror(errno));
+ exit(1); /* BIIG buffer */
+ }
+
+ c=memchr(buf,'\n',BUFFER_SIZE);
+ if (c) {
+ *c='\0';
+ length=c-buf;
+ }
+ else {
+ warn("No newline in '%s'. Dying.\n",buf);
+ exit(1);
+ }
+
+ debug("Got '%s' from squid (length: %d).\n",buf,length);
+ user=buf;
+
+ pass=memchr(buf,' ',length);
+ if (!pass) {
+ warn("Password not found. Denying access\n");
+ SEND("ERR");
+ return;
+ }
+ *pass='\0';
+ pass++;
+
+ do_authenticate(user,pass);
+
+}
+
+int main (int argc, char ** argv) {
+ if (argc > 0) { /* should always be true */
+ myname=strrchr(argv[0],'/');
+ if (myname==NULL)
+ myname=argv[0];
+ } else {
+ myname="(unknown)";
+ }
+ mypid=getpid();
+ debug("ntlm winbindd auth helper build " __DATE__ ", " __TIME__
+ " starting up...\n");
+ /* initialize FDescs */
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+
+ while(1) {
+ manage_request();
+ }
+ return 0;
+}
--- /dev/null
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+
+ winbind client common code
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Andrew Tridgell 2000
+
+ 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 "winbind_nss_config.h"
+#include "winbindd_nss.h"
+#include "config.h"
+
+
+/* Global variables. These are effectively the client state information */
+
+int winbindd_fd = -1; /* fd for winbindd socket */
+static char *excluded_domain;
+
+/* Free a response structure */
+
+void free_response(struct winbindd_response *response)
+{
+ /* Free any allocated extra_data */
+
+ if (response)
+ SAFE_FREE(response->extra_data);
+}
+
+/*
+ smbd needs to be able to exclude lookups for its own domain
+*/
+void winbind_exclude_domain(const char *domain)
+{
+ SAFE_FREE(excluded_domain);
+ excluded_domain = strdup(domain);
+}
+
+
+/* Initialise a request structure */
+
+void init_request(struct winbindd_request *request, int request_type)
+{
+ static char *domain_env;
+ static BOOL initialised;
+
+ request->length = sizeof(struct winbindd_request);
+
+ request->cmd = (enum winbindd_cmd)request_type;
+ request->pid = getpid();
+ request->domain[0] = '\0';
+
+ if (!initialised) {
+ initialised = True;
+ domain_env = getenv(WINBINDD_DOMAIN_ENV);
+ }
+
+ if (domain_env) {
+ strncpy(request->domain, domain_env,
+ sizeof(request->domain) - 1);
+ request->domain[sizeof(request->domain) - 1] = '\0';
+ }
+}
+
+/* Initialise a response structure */
+
+void init_response(struct winbindd_response *response)
+{
+ /* Initialise return value */
+
+ response->result = WINBINDD_ERROR;
+}
+
+/* Close established socket */
+
+void close_sock(void)
+{
+ if (winbindd_fd != -1) {
+ close(winbindd_fd);
+ winbindd_fd = -1;
+ }
+}
+
+/* Connect to winbindd socket */
+
+int winbind_open_pipe_sock(void)
+{
+ struct sockaddr_un sunaddr;
+ static pid_t our_pid;
+ struct stat st;
+ pstring path;
+
+ if (our_pid != getpid()) {
+ close_sock();
+ our_pid = getpid();
+ }
+
+ if (winbindd_fd != -1) {
+ return winbindd_fd;
+ }
+
+ /* Check permissions on unix socket directory */
+
+ if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
+ return -1;
+ }
+
+ if (!S_ISDIR(st.st_mode) ||
+ (st.st_uid != 0 && st.st_uid != geteuid())) {
+ return -1;
+ }
+
+ /* Connect to socket */
+
+ strncpy(path, WINBINDD_SOCKET_DIR, sizeof(path) - 1);
+ path[sizeof(path) - 1] = '\0';
+
+ strncat(path, "/", sizeof(path) - 1);
+ path[sizeof(path) - 1] = '\0';
+
+ strncat(path, WINBINDD_SOCKET_NAME, sizeof(path) - 1);
+ path[sizeof(path) - 1] = '\0';
+
+ ZERO_STRUCT(sunaddr);
+ sunaddr.sun_family = AF_UNIX;
+ strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path) - 1);
+
+ /* If socket file doesn't exist, don't bother trying to connect
+ with retry. This is an attempt to make the system usable when
+ the winbindd daemon is not running. */
+
+ if (lstat(path, &st) == -1) {
+ return -1;
+ }
+
+ /* Check permissions on unix socket file */
+
+ if (!S_ISSOCK(st.st_mode) ||
+ (st.st_uid != 0 && st.st_uid != geteuid())) {
+ return -1;
+ }
+
+ /* Connect to socket */
+
+ if ((winbindd_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ return -1;
+ }
+
+ if (connect(winbindd_fd, (struct sockaddr *)&sunaddr,
+ sizeof(sunaddr)) == -1) {
+ close_sock();
+ return -1;
+ }
+
+ return winbindd_fd;
+}
+
+/* Write data to winbindd socket with timeout */
+
+int write_sock(void *buffer, int count)
+{
+ int result, nwritten;
+
+ /* Open connection to winbind daemon */
+
+ restart:
+
+ if (winbind_open_pipe_sock() == -1) {
+ return -1;
+ }
+
+ /* Write data to socket */
+
+ nwritten = 0;
+
+ while(nwritten < count) {
+ struct timeval tv;
+ fd_set r_fds;
+
+ /* Catch pipe close on other end by checking if a read()
+ call would not block by calling select(). */
+
+ FD_ZERO(&r_fds);
+ FD_SET(winbindd_fd, &r_fds);
+ ZERO_STRUCT(tv);
+
+ if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {
+ close_sock();
+ return -1; /* Select error */
+ }
+
+ /* Write should be OK if fd not available for reading */
+
+ if (!FD_ISSET(winbindd_fd, &r_fds)) {
+
+ /* Do the write */
+
+ result = write(winbindd_fd,
+ (char *)buffer + nwritten,
+ count - nwritten);
+
+ if ((result == -1) || (result == 0)) {
+
+ /* Write failed */
+
+ close_sock();
+ return -1;
+ }
+
+ nwritten += result;
+
+ } else {
+
+ /* Pipe has closed on remote end */
+
+ close_sock();
+ goto restart;
+ }
+ }
+
+ return nwritten;
+}
+
+/* Read data from winbindd socket with timeout */
+
+static int read_sock(void *buffer, int count)
+{
+ int result = 0, nread = 0;
+
+ /* Read data from socket */
+
+ while(nread < count) {
+
+ result = read(winbindd_fd, (char *)buffer + nread,
+ count - nread);
+
+ if ((result == -1) || (result == 0)) {
+
+ /* Read failed. I think the only useful thing we
+ can do here is just return -1 and fail since the
+ transaction has failed half way through. */
+
+ close_sock();
+ return -1;
+ }
+
+ nread += result;
+ }
+
+ return result;
+}
+
+/* Read reply */
+
+int read_reply(struct winbindd_response *response)
+{
+ int result1, result2 = 0;
+
+ if (!response) {
+ return -1;
+ }
+
+ /* Read fixed length response */
+
+ if ((result1 = read_sock(response, sizeof(struct winbindd_response)))
+ == -1) {
+
+ return -1;
+ }
+
+ /* We actually send the pointer value of the extra_data field from
+ the server. This has no meaning in the client's address space
+ so we clear it out. */
+
+ response->extra_data = NULL;
+
+ /* Read variable length response */
+
+ if (response->length > sizeof(struct winbindd_response)) {
+ int extra_data_len = response->length -
+ sizeof(struct winbindd_response);
+
+ /* Mallocate memory for extra data */
+
+ if (!(response->extra_data = malloc(extra_data_len))) {
+ return -1;
+ }
+
+ if ((result2 = read_sock(response->extra_data, extra_data_len))
+ == -1) {
+ free_response(response);
+ return -1;
+ }
+ }
+
+ /* Return total amount of data read */
+
+ return result1 + result2;
+}
+
+/*
+ * send simple types of requests
+ */
+
+NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
+{
+ struct winbindd_request lrequest;
+
+ /* Check for our tricky environment variable */
+
+ if (getenv(WINBINDD_DONT_ENV)) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* smbd may have excluded this domain */
+ if (excluded_domain &&
+ strcasecmp(excluded_domain, request->domain) == 0) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ if (!request) {
+ ZERO_STRUCT(lrequest);
+ request = &lrequest;
+ }
+
+ /* Fill in request and send down pipe */
+
+ init_request(request, req_type);
+
+ if (write_sock(request, sizeof(*request)) == -1) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ return NSS_STATUS_SUCCESS;
+}
+
+/*
+ * Get results from winbindd request
+ */
+
+NSS_STATUS winbindd_get_response(struct winbindd_response *response)
+{
+ struct winbindd_response lresponse;
+
+ if (!response) {
+ ZERO_STRUCT(lresponse);
+ response = &lresponse;
+ }
+
+ init_response(response);
+
+ /* Wait for reply */
+ if (read_reply(response) == -1) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ /* Throw away extra data if client didn't request it */
+ if (response == &lresponse) {
+ free_response(response);
+ }
+
+ /* Copy reply data from socket */
+ if (response->result != WINBINDD_OK) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ return NSS_STATUS_SUCCESS;
+}
+
+/* Handle simple types of requests */
+
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ NSS_STATUS status;
+
+ status = winbindd_send_request(req_type, request);
+ if (status != NSS_STATUS_SUCCESS)
+ return(status);
+ return winbindd_get_response(response);
+}
--- /dev/null
+/*
+ * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>,
+ *
+ * Distributed freely under the terms of the GNU General Public License,
+ * version 2. See the file COPYING for licensing details
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ */
+
+#ifndef _WBNTLM_H_
+#define _WBNTLM_H_
+
+#include "config.h"
+#include "ntlmauth.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+/*************** CONFIGURATION ***************/
+#ifndef DEBUG
+#define DEBUG
+#endif
+
+/* the attempted entropy source. If it doesn't exist, random() is uesed */
+#define ENTROPY_SOURCE "/dev/urandom"
+
+#define DOMAIN "GCSINT" /* TODO: fix ntlm_make_challenge */
+
+/************* END CONFIGURATION *************/
+
+/* Debugging stuff */
+extern char *myname;
+static char *__foo;
+extern pid_t mypid;
+extern char debug_enabled;
+
+#ifdef DEBUG
+#define __DO_DEBUG 1
+#else
+#define __DO_DEBUG 0
+#endif
+
+#ifdef __GNUC__ /* this is really a gcc-ism */
+#define warn(X...) fprintf(stderr,"%s[%d](%s:%d): ", myname, mypid, \
+ ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\
+ __LINE__);\
+ fprintf(stderr,X)
+#define debug(X...) if(__DO_DEBUG && debug_enabled) { warn(X); }
+#else /* __GNUC__ */
+static void
+debug(char *format,...)
+{
+}
+static void
+warn(char *format,...)
+{
+}
+#endif /* __GNUC__ */
+
+
+
+/* A couple of harmless helper macros */
+#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
+#ifdef __GNUC__
+#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); \
+ printf(X "\n",Y)
+#else
+/* no gcc, no debugging. varargs macros are a gcc extension */
+#define SEND2 printf
+#endif
+
+typedef enum {
+ YES,
+ NO,
+ DONTKNOW
+} tristate;
+
+#define CHALLENGE_LEN 8
+#define BUFFER_SIZE 2010
+
+#endif /* _WBNTLM_H_ */
--- /dev/null
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+
+ Winbind daemon for ntdom nss module
+
+ Copyright (C) Tim Potter 2000
+
+ 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_CONFIG_H
+#define _WINBIND_NSS_CONFIG_H
+
+/* Include header files from data in config.h file */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_UNIXSOCKET
+#include <sys/un.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <pwd.h>
+#include "samba_nss.h"
+
+/* Declarations for functions in winbind_nss.c
+ needed in winbind_nss_solaris.c (solaris wrapper to nss) */
+
+NSS_STATUS _nss_winbind_setpwent(void);
+NSS_STATUS _nss_winbind_endpwent(void);
+NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result,
+ char* buffer, size_t buflen, int* errnop);
+
+NSS_STATUS _nss_winbind_setgrent(void);
+NSS_STATUS _nss_winbind_endgrent(void);
+NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getgrnam_r(const char *name,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop);
+NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop);
+
+/* I'm trying really hard not to include anything from smb.h with the
+ result of some silly looking redeclaration of structures. */
+
+#ifndef _PSTRING
+#define _PSTRING
+#define PSTRING_LEN 1024
+#define FSTRING_LEN 256
+typedef char pstring[PSTRING_LEN];
+typedef char fstring[FSTRING_LEN];
+#endif
+
+#ifndef _BOOL
+#define _BOOL /* So we don't typedef BOOL again in vfs.h */
+#define False (0)
+#define True (1)
+#define Auto (2)
+typedef int BOOL;
+#endif
+
+#if !defined(uint32)
+#if (SIZEOF_INT == 4)
+#define uint32 unsigned int
+#elif (SIZEOF_LONG == 4)
+#define uint32 unsigned long
+#elif (SIZEOF_SHORT == 4)
+#define uint32 unsigned short
+#endif
+#endif
+
+#if !defined(uint16)
+#if (SIZEOF_SHORT == 4)
+#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;
+#else /* SIZEOF_SHORT != 4 */
+#define uint16 unsigned short
+#endif /* SIZEOF_SHORT != 4 */
+#endif
+
+#ifndef uint8
+#define uint8 unsigned char
+#endif
+
+/* zero a structure */
+#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
+
+/* zero a structure given a pointer to the structure */
+#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }
+
+/* Some systems (SCO) treat UNIX domain sockets as FIFOs */
+
+#ifndef S_IFSOCK
+#define S_IFSOCK S_IFIFO
+#endif
+
+#ifndef S_ISSOCK
+#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK)
+#endif
+
+#endif
--- /dev/null
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+
+ Winbind daemon for ntdom nss module
+
+ Copyright (C) Tim Potter 2000
+
+ 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 SAFE_FREE
+#define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0)
+#endif
+
+#ifndef _WINBINDD_NTDOM_H
+#define _WINBINDD_NTDOM_H
+
+#define WINBINDD_SOCKET_NAME "pipe" /* Name of PF_UNIX socket */
+#define WINBINDD_SOCKET_DIR "/tmp/.winbindd" /* Name of PF_UNIX dir */
+
+#define WINBINDD_DOMAIN_ENV "WINBINDD_DOMAIN" /* Environment variables */
+#define WINBINDD_DONT_ENV "_NO_WINBINDD"
+
+/* Update this when you change the interface. */
+
+#define WINBIND_INTERFACE_VERSION 2
+
+/* Socket commands */
+
+enum winbindd_cmd {
+
+ WINBINDD_INTERFACE_VERSION, /* Always a well known value */
+
+ /* Get users and groups */
+
+ WINBINDD_GETPWNAM,
+ WINBINDD_GETPWUID,
+ WINBINDD_GETGRNAM,
+ WINBINDD_GETGRGID,
+ WINBINDD_GETGROUPS,
+
+ /* Enumerate users and groups */
+
+ WINBINDD_SETPWENT,
+ WINBINDD_ENDPWENT,
+ WINBINDD_GETPWENT,
+ WINBINDD_SETGRENT,
+ WINBINDD_ENDGRENT,
+ WINBINDD_GETGRENT,
+
+ /* PAM authenticate and password change */
+
+ WINBINDD_PAM_AUTH,
+ WINBINDD_PAM_AUTH_CRAP,
+ WINBINDD_PAM_CHAUTHTOK,
+
+ /* List various things */
+
+ WINBINDD_LIST_USERS, /* List w/o rid->id mapping */
+ WINBINDD_LIST_GROUPS, /* Ditto */
+ WINBINDD_LIST_TRUSTDOM,
+
+ /* SID conversion */
+
+ WINBINDD_LOOKUPSID,
+ WINBINDD_LOOKUPNAME,
+
+ /* Lookup functions */
+
+ WINBINDD_SID_TO_UID,
+ WINBINDD_SID_TO_GID,
+ WINBINDD_UID_TO_SID,
+ WINBINDD_GID_TO_SID,
+
+ /* Miscellaneous other stuff */
+
+ WINBINDD_CHECK_MACHACC, /* Check machine account pw works */
+ WINBINDD_PING, /* Just tell me winbind is running */
+ WINBINDD_INFO, /* Various bit of info. Currently just tidbits */
+
+ /* Placeholder for end of cmd list */
+
+ WINBINDD_NUM_CMDS
+};
+
+/* Winbind request structure */
+
+struct winbindd_request {
+ uint32 length;
+ enum winbindd_cmd cmd; /* Winbindd command to execute */
+ pid_t pid; /* pid of calling process */
+
+ union {
+ fstring username; /* getpwnam */
+ fstring groupname; /* getgrnam */
+ uid_t uid; /* getpwuid, uid_to_sid */
+ gid_t gid; /* getgrgid, gid_to_sid */
+ struct {
+ fstring user;
+ fstring pass;
+ } auth; /* pam_winbind auth module */
+ struct {
+ unsigned char chal[8];
+ fstring user;
+ fstring domain;
+ fstring lm_resp;
+ uint16 lm_resp_len;
+ fstring nt_resp;
+ uint16 nt_resp_len;
+ } auth_crap;
+ struct {
+ fstring user;
+ fstring oldpass;
+ fstring newpass;
+ } chauthtok; /* pam_winbind passwd module */
+ fstring sid; /* lookupsid, sid_to_[ug]id */
+ fstring name; /* lookupname */
+ uint32 num_entries; /* getpwent, getgrent */
+ } data;
+ fstring domain; /* {set,get,end}{pw,gr}ent() */
+};
+
+/* Response values */
+
+enum winbindd_result {
+ WINBINDD_ERROR,
+ WINBINDD_OK
+};
+
+/* Winbind response structure */
+
+struct winbindd_response {
+
+ /* Header information */
+
+ uint32 length; /* Length of response */
+ enum winbindd_result result; /* Result code */
+
+ /* Fixed length return data */
+
+ union {
+ int interface_version; /* Try to ensure this is always in the same spot... */
+
+ /* getpwnam, getpwuid */
+
+ struct winbindd_pw {
+ fstring pw_name;
+ fstring pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ fstring pw_gecos;
+ fstring pw_dir;
+ fstring pw_shell;
+ } pw;
+
+ /* getgrnam, getgrgid */
+
+ struct winbindd_gr {
+ fstring gr_name;
+ fstring gr_passwd;
+ gid_t gr_gid;
+ int num_gr_mem;
+ int gr_mem_ofs; /* offset to group membership */
+ } gr;
+
+ uint32 num_entries; /* getpwent, getgrent */
+ struct winbindd_sid {
+ fstring sid; /* lookupname, [ug]id_to_sid */
+ int type;
+ } sid;
+ struct winbindd_name {
+ fstring name; /* lookupsid */
+ int type;
+ } name;
+ uid_t uid; /* sid_to_uid */
+ gid_t gid; /* sid_to_gid */
+ struct winbindd_info {
+ char winbind_separator;
+ fstring samba_version;
+ } info;
+ } data;
+
+ /* Variable length return data */
+
+ void *extra_data; /* getgrnam, getgrgid, getgrent */
+};
+
+#endif
# Makefile for storage modules in the Squid Object Cache server
#
-# $Id: Makefile.am,v 1.4 2002/05/19 15:07:55 hno Exp $
+# $Id: Makefile.am,v 1.5 2002/05/19 23:42:42 hno Exp $
#
-DIST_SUBDIRS = fakeauth no_check SMB
+DIST_SUBDIRS = fakeauth no_check SMB winbind
SUBDIRS = @NTLM_AUTH_HELPERS@
--- /dev/null
+#
+# Makefile for the Squid Object Cache server
+#
+# $Id: Makefile.am,v 1.1 2002/05/19 23:42:42 hno Exp $
+#
+
+libexec_PROGRAMS = wb_ntlmauth
+wb_ntlmauth_SOURCES = wb_ntlm_auth.c wb_common.c
+INCLUDES = -I. -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src
+LDADD = -L$(top_builddir)/lib -lmiscutil -lntlmauth -lm
--- /dev/null
+--- samba-HEAD/source/nsswitch/wb_common.c Sat Jan 12 23:12:11 2002
++++ squid-ntlm/src/auth/ntlm/helpers/winbind/wb_common.c Sat Jan 12 23:45:03 2002
+@@ -25,6 +25,8 @@
+
+ #include "winbind_nss_config.h"
+ #include "winbindd_nss.h"
++#include "config.h"
++
+
+ /* Global variables. These are effectively the client state information */
+
--- /dev/null
+--- samba-HEAD/source/nsswitch/winbind_nss_config.h Wed Sep 5 10:11:16 2001
++++ squid-ntlm/src/auth/ntlm/helpers/winbind/winbind_nss_config.h Sat Nov 24 00:32:05 2001
+@@ -27,7 +27,7 @@
+
+ /* Include header files from data in config.h file */
+
+-#include <config.h>
++#include "config.h"
+
+ #include <stdio.h>
+
+@@ -63,7 +63,7 @@
+ #include <sys/stat.h>
+ #include <errno.h>
+ #include <pwd.h>
+-#include "nsswitch/nss.h"
++#include "samba_nss.h"
+
+ /* Declarations for functions in winbind_nss.c
+ needed in winbind_nss_solaris.c (solaris wrapper to nss) */
--- /dev/null
+#ifndef _NSSWITCH_NSS_H
+#define _NSSWITCH_NSS_H
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+
+ a common place to work out how to define NSS_STATUS on various
+ platforms
+
+ Copyright (C) Tim Potter 2000
+
+ 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.
+*/
+
+#ifdef HAVE_NSS_COMMON_H
+
+/* Sun Solaris */
+
+#include <nss_common.h>
+#include <nss_dbdefs.h>
+#include <nsswitch.h>
+
+typedef nss_status_t NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS NSS_SUCCESS
+#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+
+#elif HAVE_NSS_H
+
+/* GNU */
+
+#include <nss.h>
+
+typedef enum nss_status NSS_STATUS;
+
+#elif HAVE_NS_API_H
+
+/* SGI IRIX */
+
+/* following required to prevent warnings of double definition
+ * of datum from ns_api.h
+*/
+#ifdef DATUM
+#define _DATUM_DEFINED
+#endif
+
+#include <ns_api.h>
+
+typedef enum
+{
+ NSS_STATUS_SUCCESS=NS_SUCCESS,
+ NSS_STATUS_NOTFOUND=NS_NOTFOUND,
+ NSS_STATUS_UNAVAIL=NS_UNAVAIL,
+ NSS_STATUS_TRYAGAIN=NS_TRYAGAIN
+} NSS_STATUS;
+
+#define NSD_MEM_STATIC 0
+#define NSD_MEM_VOLATILE 1
+#define NSD_MEM_DYNAMIC 2
+
+#elif defined(HPUX)
+/* HP-UX 11 */
+
+#include "nsswitch/hp_nss_common.h"
+#include "nsswitch/hp_nss_dbdefs.h"
+#include <nsswitch.h>
+
+#ifndef _HAVE_TYPEDEF_NSS_STATUS
+#define _HAVE_TYPEDEF_NSS_STATUS
+typedef nss_status_t NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS NSS_SUCCESS
+#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+#endif /* HPUX */
+
+#else /* Nothing's defined. Neither gnu nor sun nor hp */
+
+typedef enum
+{
+ NSS_STATUS_SUCCESS=0,
+ NSS_STATUS_NOTFOUND=1,
+ NSS_STATUS_UNAVAIL=2,
+ NSS_STATUS_TRYAGAIN=3
+} NSS_STATUS;
+
+#endif
+
+#endif /* _NSSWITCH_NSS_H */
--- /dev/null
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+
+ winbind client common code
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Andrew Tridgell 2000
+
+ 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 "winbind_nss_config.h"
+#include "winbindd_nss.h"
+#include "config.h"
+
+
+/* Global variables. These are effectively the client state information */
+
+int winbindd_fd = -1; /* fd for winbindd socket */
+static char *excluded_domain;
+
+/* Free a response structure */
+
+void
+free_response(struct winbindd_response *response)
+{
+ /* Free any allocated extra_data */
+
+ if (response)
+ SAFE_FREE(response->extra_data);
+}
+
+/*
+ smbd needs to be able to exclude lookups for its own domain
+*/
+void
+winbind_exclude_domain(const char *domain)
+{
+ SAFE_FREE(excluded_domain);
+ excluded_domain = strdup(domain);
+}
+
+
+/* Initialise a request structure */
+
+void
+init_request(struct winbindd_request *request, int request_type)
+{
+ static char *domain_env;
+ static BOOL initialised;
+
+ request->length = sizeof(struct winbindd_request);
+
+ request->cmd = (enum winbindd_cmd) request_type;
+ request->pid = getpid();
+ request->domain[0] = '\0';
+
+ if (!initialised) {
+ initialised = True;
+ domain_env = getenv(WINBINDD_DOMAIN_ENV);
+ }
+
+ if (domain_env) {
+ strncpy(request->domain, domain_env, sizeof(request->domain) - 1);
+ request->domain[sizeof(request->domain) - 1] = '\0';
+ }
+}
+
+/* Initialise a response structure */
+
+void
+init_response(struct winbindd_response *response)
+{
+ /* Initialise return value */
+
+ response->result = WINBINDD_ERROR;
+}
+
+/* Close established socket */
+
+void
+close_sock(void)
+{
+ if (winbindd_fd != -1) {
+ close(winbindd_fd);
+ winbindd_fd = -1;
+ }
+}
+
+/* Connect to winbindd socket */
+
+int
+winbind_open_pipe_sock(void)
+{
+ struct sockaddr_un sunaddr;
+ static pid_t our_pid;
+ struct stat st;
+ pstring path;
+
+ if (our_pid != getpid()) {
+ close_sock();
+ our_pid = getpid();
+ }
+
+ if (winbindd_fd != -1) {
+ return winbindd_fd;
+ }
+
+ /* Check permissions on unix socket directory */
+
+ if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
+ return -1;
+ }
+
+ if (!S_ISDIR(st.st_mode) || (st.st_uid != 0 && st.st_uid != geteuid())) {
+ return -1;
+ }
+
+ /* Connect to socket */
+
+ strncpy(path, WINBINDD_SOCKET_DIR, sizeof(path) - 1);
+ path[sizeof(path) - 1] = '\0';
+
+ strncat(path, "/", sizeof(path) - 1);
+ path[sizeof(path) - 1] = '\0';
+
+ strncat(path, WINBINDD_SOCKET_NAME, sizeof(path) - 1);
+ path[sizeof(path) - 1] = '\0';
+
+ ZERO_STRUCT(sunaddr);
+ sunaddr.sun_family = AF_UNIX;
+ strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path) - 1);
+
+ /* If socket file doesn't exist, don't bother trying to connect
+ * with retry. This is an attempt to make the system usable when
+ * the winbindd daemon is not running. */
+
+ if (lstat(path, &st) == -1) {
+ return -1;
+ }
+
+ /* Check permissions on unix socket file */
+
+ if (!S_ISSOCK(st.st_mode) || (st.st_uid != 0 && st.st_uid != geteuid())) {
+ return -1;
+ }
+
+ /* Connect to socket */
+
+ if ((winbindd_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ return -1;
+ }
+
+ if (connect(winbindd_fd, (struct sockaddr *) &sunaddr,
+ sizeof(sunaddr)) == -1) {
+ close_sock();
+ return -1;
+ }
+
+ return winbindd_fd;
+}
+
+/* Write data to winbindd socket with timeout */
+
+int
+write_sock(void *buffer, int count)
+{
+ int result, nwritten;
+
+ /* Open connection to winbind daemon */
+
+ restart:
+
+ if (winbind_open_pipe_sock() == -1) {
+ return -1;
+ }
+
+ /* Write data to socket */
+
+ nwritten = 0;
+
+ while (nwritten < count) {
+ struct timeval tv;
+ fd_set r_fds;
+
+ /* Catch pipe close on other end by checking if a read()
+ * call would not block by calling select(). */
+
+ FD_ZERO(&r_fds);
+ FD_SET(winbindd_fd, &r_fds);
+ ZERO_STRUCT(tv);
+
+ if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {
+ close_sock();
+ return -1; /* Select error */
+ }
+
+ /* Write should be OK if fd not available for reading */
+
+ if (!FD_ISSET(winbindd_fd, &r_fds)) {
+
+ /* Do the write */
+
+ result = write(winbindd_fd,
+ (char *) buffer + nwritten, count - nwritten);
+
+ if ((result == -1) || (result == 0)) {
+
+ /* Write failed */
+
+ close_sock();
+ return -1;
+ }
+
+ nwritten += result;
+
+ } else {
+
+ /* Pipe has closed on remote end */
+
+ close_sock();
+ goto restart;
+ }
+ }
+
+ return nwritten;
+}
+
+/* Read data from winbindd socket with timeout */
+
+static int
+read_sock(void *buffer, int count)
+{
+ int result = 0, nread = 0;
+
+ /* Read data from socket */
+
+ while (nread < count) {
+
+ result = read(winbindd_fd, (char *) buffer + nread, count - nread);
+
+ if ((result == -1) || (result == 0)) {
+
+ /* Read failed. I think the only useful thing we
+ * can do here is just return -1 and fail since the
+ * transaction has failed half way through. */
+
+ close_sock();
+ return -1;
+ }
+
+ nread += result;
+ }
+
+ return result;
+}
+
+/* Read reply */
+
+int
+read_reply(struct winbindd_response *response)
+{
+ int result1, result2 = 0;
+
+ if (!response) {
+ return -1;
+ }
+
+ /* Read fixed length response */
+
+ if ((result1 = read_sock(response, sizeof(struct winbindd_response)))
+ == -1) {
+
+ return -1;
+ }
+
+ /* We actually send the pointer value of the extra_data field from
+ * the server. This has no meaning in the client's address space
+ * so we clear it out. */
+
+ response->extra_data = NULL;
+
+ /* Read variable length response */
+
+ if (response->length > sizeof(struct winbindd_response)) {
+ int extra_data_len = response->length -
+ sizeof(struct winbindd_response);
+
+ /* Mallocate memory for extra data */
+
+ if (!(response->extra_data = malloc(extra_data_len))) {
+ return -1;
+ }
+
+ if ((result2 = read_sock(response->extra_data, extra_data_len))
+ == -1) {
+ free_response(response);
+ return -1;
+ }
+ }
+
+ /* Return total amount of data read */
+
+ return result1 + result2;
+}
+
+/*
+ * send simple types of requests
+ */
+
+NSS_STATUS
+winbindd_send_request(int req_type, struct winbindd_request * request)
+{
+ struct winbindd_request lrequest;
+
+ /* Check for our tricky environment variable */
+
+ if (getenv(WINBINDD_DONT_ENV)) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* smbd may have excluded this domain */
+ if (excluded_domain && strcasecmp(excluded_domain, request->domain) == 0) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ if (!request) {
+ ZERO_STRUCT(lrequest);
+ request = &lrequest;
+ }
+
+ /* Fill in request and send down pipe */
+
+ init_request(request, req_type);
+
+ if (write_sock(request, sizeof(*request)) == -1) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ return NSS_STATUS_SUCCESS;
+}
+
+/*
+ * Get results from winbindd request
+ */
+
+NSS_STATUS
+winbindd_get_response(struct winbindd_response * response)
+{
+ struct winbindd_response lresponse;
+
+ if (!response) {
+ ZERO_STRUCT(lresponse);
+ response = &lresponse;
+ }
+
+ init_response(response);
+
+ /* Wait for reply */
+ if (read_reply(response) == -1) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ /* Throw away extra data if client didn't request it */
+ if (response == &lresponse) {
+ free_response(response);
+ }
+
+ /* Copy reply data from socket */
+ if (response->result != WINBINDD_OK) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ return NSS_STATUS_SUCCESS;
+}
+
+/* Handle simple types of requests */
+
+NSS_STATUS
+winbindd_request(int req_type,
+ struct winbindd_request * request, struct winbindd_response * response)
+{
+ NSS_STATUS status;
+
+ status = winbindd_send_request(req_type, request);
+ if (status != NSS_STATUS_SUCCESS)
+ return (status);
+ return winbindd_get_response(response);
+}
--- /dev/null
+/*
+ * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
+ * (C) 2002 Andrew Bartlett <abartlet@samba.org>
+ *
+ * Distributed freely under the terms of the GNU General Public License,
+ * version 2. See the file COPYING for licensing details
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+/*
+ * TODO:
+ * -add handling of the -d flag
+ * -move all squid-helper-protocol-related operations to helper functions
+ * -remove the hard-coded target NT domain name
+ *
+ * - MAYBE move squid-helper-protocol-related opetations to an external
+ * library?
+ */
+
+
+#include "wbntlm.h"
+#include "util.h"
+/* stdio.h is included in wbntlm.h */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/time.h> /* for gettimeofday */
+#include <errno.h> /* BUG: is this portable? */
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#include "winbind_nss_config.h"
+#include "winbindd_nss.h"
+
+#ifndef min
+#define min(x,y) ((x)<(y)?(x):(y))
+#endif
+
+void
+authfail(char *domain, char *user, char *reason)
+{
+ /* TODO: -move away from SEND-type gcc-isms
+ * -prepare for protocol extension as soon as rbcollins is ready
+ */
+ SEND2("NA %s\\%s auth failure because: %s", domain, user, reason);
+}
+
+void
+authok(const char *domain, const char *user)
+{
+ SEND2("AF %s\\%s", domain, user);
+}
+
+void
+sendchallenge(const char *challenge)
+{
+ SEND2("TT %s", challenge);
+}
+
+void
+helperfail(const char *reason)
+{
+ SEND2("BH %s", reason);
+}
+
+char debug_enabled = 0;
+char *myname;
+pid_t mypid;
+
+static void
+lc(char *string)
+{
+ char *p = string, c;
+ while ((c = *p)) {
+ *p = tolower(c);
+ p++;
+ }
+}
+
+static void
+uc(char *string)
+{
+ char *p = string, c;
+ while ((c = *p)) {
+ *p = toupper(c);
+ p++;
+ }
+}
+
+
+
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request, struct winbindd_response *response);
+
+
+static tristate have_urandom = DONTKNOW;
+FILE *urandom_file = NULL;
+
+void
+init_random()
+{
+ if (have_urandom == DONTKNOW) {
+ int result = 0;
+ struct stat st;
+ result = stat(ENTROPY_SOURCE, &st);
+ if (result != 0 || !(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
+ debug("Entropy source " ENTROPY_SOURCE " is unavailable\n");
+ have_urandom = NO;
+ }
+ if ((urandom_file = fopen(ENTROPY_SOURCE, "r")) == NULL) {
+ unsigned int seed;
+ struct timeval t;
+ warn("Can't open entropy source " ENTROPY_SOURCE "\n");
+ have_urandom = NO;
+ gettimeofday(&t, NULL);
+ seed = squid_random() * getpid() * t.tv_sec * t.tv_usec;
+ squid_srandom(seed);
+ } else {
+ have_urandom = YES;
+ }
+ }
+}
+
+static unsigned char challenge[CHALLENGE_LEN + 1];
+static char *
+build_challenge(void)
+{
+ size_t gotchars;
+ unsigned char j;
+ switch (have_urandom) {
+ case YES:
+ if ((gotchars = fread(&challenge, CHALLENGE_LEN, 1, urandom_file)) == 0) {
+ /* couldn't get a challenge. Fall back to random() and friends.
+ * notice that even a single changed byte is good enough for us */
+ have_urandom = NO;
+ return build_challenge();
+ }
+ return challenge;
+ case NO:
+ if (!(squid_random() % 100)) { /* sometimes */
+ init_random();
+ }
+ for (j = 0; j < CHALLENGE_LEN; j++)
+ challenge[j] = (unsigned char) (squid_random() % 256);
+ return challenge;
+ default:
+ warn("Critical internal error. Somebody forgot to initialize "
+ "the random system. Exiting.\n");
+ exit(1);
+ }
+}
+
+lstring lmhash, nthash;
+static char have_nthash = 0; /* simple flag. A tad dirty.. */
+
+void
+do_authenticate(ntlm_authenticate * auth, int auth_length)
+{
+ lstring tmp;
+ int tocopy;
+ NSS_STATUS winbindd_result;
+ struct winbindd_request request;
+ struct winbindd_response response;
+ char *domain, *user;
+
+ memset(&request, 0, sizeof(struct winbindd_request));
+
+ memset(&response, 0, sizeof(struct winbindd_response));
+
+ /* domain */
+ tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->domain);
+ if (tmp.str == NULL || tmp.l == 0) { /* no domain supplied */
+ request.data.auth_crap.domain[0] = 0;
+ } else {
+ tocopy = min(tmp.l + 1, sizeof(fstring));
+ xstrncpy(request.data.auth_crap.domain, tmp.str, tocopy);
+ }
+
+ domain = request.data.auth_crap.domain; /* just a shortcut */
+
+ /* username */
+ tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->user);
+ if (tmp.str == NULL || tmp.l == 0) {
+ authfail(domain, "-", "No username in request");
+ return;
+ }
+
+ tocopy = min(sizeof(fstring), tmp.l + 1);
+ xstrncpy(request.data.auth_crap.user, tmp.str, tocopy);
+ user = request.data.auth_crap.user;
+
+ /* now the LM hash */
+ lmhash = ntlm_fetch_string((char *) auth, auth_length, &auth->lmresponse);
+ switch (lmhash.l) {
+ case 0:
+ warn("No lm hash provided by user %s\\%s\n", domain, user);
+ request.data.auth_crap.lm_resp_len = 0;
+ break;
+ case 24:
+ memcpy(request.data.auth_crap.lm_resp, lmhash.str, 24);
+ request.data.auth_crap.lm_resp_len = 24;
+ break;
+ default:
+ authfail(domain, user, "Broken LM hash response");
+ return;
+ }
+
+ nthash = ntlm_fetch_string((char *) auth, auth_length, &auth->ntresponse);
+ switch (nthash.l) {
+ case 0:
+ debug("no nthash\n");
+ request.data.auth_crap.nt_resp_len = 0;
+ break;
+ case 24:
+ memcpy(request.data.auth_crap.nt_resp, nthash.str, 24);
+ request.data.auth_crap.nt_resp_len = 24;
+ break;
+ default:
+ debug("nthash len = %d\n", nthash.l);
+ authfail(domain, user, "Broken NT hash response");
+ return;
+ }
+
+ debug("Checking user '%s\\%s' lmhash len =%d, have_nthash=%d, "
+ "nthash len=%d\n", domain, user, lmhash.l, have_nthash, nthash.l);
+
+ memcpy(request.data.auth_crap.chal, challenge, CHALLENGE_LEN);
+
+ winbindd_result = winbindd_request(WINBINDD_PAM_AUTH_CRAP,
+ &request, &response);
+ debug("winbindd result: %d\n", winbindd_result);
+
+ if (winbindd_result == WINBINDD_OK) {
+ lc(domain);
+ lc(user);
+ authok(domain, user);
+ } else {
+ char error_buf[200];
+ snprintf(error_buf, sizeof(error_buf), "Authentication Failure (%s)",
+ response.data.auth.error_string);
+ authfail(domain, user, error_buf);
+ }
+ return; /* useless */
+}
+
+void
+manage_request(char *target_domain)
+{
+ char buf[BUFFER_SIZE + 1];
+ char *c, *decoded;
+ ntlmhdr *fast_header;
+
+
+ if (fgets(buf, BUFFER_SIZE, stdin) == NULL) {
+ warn("fgets() failed! dying..... errno=%d (%s)\n", errno,
+ strerror(errno));
+ exit(1); /* BIIG buffer */
+ }
+
+ c = memchr(buf, '\n', BUFFER_SIZE);
+ if (c)
+ *c = '\0';
+ else {
+ warn("No newline in '%s'. Dying.\n", buf);
+ exit(1);
+ }
+
+ debug("Got '%s' from squid.\n", buf);
+ if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */
+ sendchallenge(ntlm_make_challenge(target_domain, NULL,
+ build_challenge(), CHALLENGE_LEN));
+ return;
+ }
+ if (strncmp(buf, "KK ", 3) != 0) { /* not an auth-request */
+ helperfail("illegal request received");
+ warn("Illegal request received: '%s'\n", buf);
+ return;
+ }
+ /* At this point I'm sure it's a KK */
+ decoded = base64_decode(buf + 3);
+ if (!decoded) { /* decoding failure, return error */
+ authfail("-", "-", "Auth-format error, base64-decoding error");
+ return;
+ }
+ fast_header = (struct _ntlmhdr *) decoded;
+
+ /* sanity-check: it IS a NTLMSSP packet, isn't it? */
+ if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) {
+ authfail("-", "-", "Broken NTLM packet, missing NTLMSSP signature");
+ return;
+ }
+ /* Understand what we got */
+ switch (fast_header->type) {
+ case NTLM_NEGOTIATE:
+ authfail("-", "-", "Received neg-request while expecting auth packet");
+ return;
+ case NTLM_CHALLENGE:
+ authfail("-", "-", "Received challenge. Refusing to abide");
+ return;
+ case NTLM_AUTHENTICATE:
+ do_authenticate((ntlm_authenticate *) decoded,
+ (strlen(buf) - 3) * 3 / 4);
+ return;
+ default:
+ helperfail("Unknown authentication packet type");
+ return;
+ }
+ /* notreached */
+ return;
+}
+
+static char *
+get_winbind_domain(void)
+{
+ struct winbindd_response response;
+ char *domain;
+
+ ZERO_STRUCT(response);
+
+ /* Send off request */
+
+ if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) !=
+ NSS_STATUS_SUCCESS) {
+ warn("could not obtain winbind domain name!\n");
+ exit(1);
+ }
+
+ domain = strdup(response.data.domain_name);
+ uc(domain);
+
+ warn("target domain is %s\n", domain);
+ return domain;
+}
+
+char *
+process_options(int argc, char *argv[])
+{
+ int opt;
+ char *target_domain = NULL;
+
+ while (-1 != (opt = getopt(argc, argv, "d"))) {
+ switch (opt) {
+ case 'd':
+ debug_enabled = 1;
+ break;
+ default:
+ warn("Unknown option: -%c. Exiting\n", opt);
+ exit(1);
+ break; /* not reached */
+ }
+ if (optind >= argc - 1) {
+ target_domain = argv[optind];
+ warn("target domain is %s\n", target_domain);
+ }
+ }
+ return target_domain;
+}
+
+void
+check_winbindd()
+{
+ NSS_STATUS r;
+ struct winbindd_request request;
+ struct winbindd_response response;
+ r = winbindd_request(WINBINDD_INTERFACE_VERSION, &request, &response);
+ if (r != WINBINDD_OK) {
+ warn("Can't contact winbindd. Dying\n");
+ exit(1);
+ }
+ if (response.data.interface_version != WINBIND_INTERFACE_VERSION) {
+ warn("Winbind protocol mismatch. Align squid and samba. Dying\n");
+ exit(1);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ char *target_domain;
+ if (argc > 0) { /* should always be true */
+ myname = strrchr(argv[0], '/');
+ if (myname == NULL)
+ myname = argv[0];
+ else
+ myname++;
+ } else {
+ myname = "(unknown)";
+ }
+ mypid = getpid();
+ target_domain = process_options(argc, argv);
+ debug("ntlm winbindd auth helper build " __DATE__ ", " __TIME__
+ " starting up...\n");
+
+ check_winbindd();
+
+ if (target_domain == NULL) {
+ target_domain = get_winbind_domain();
+ }
+
+ /* initialize FDescs */
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+ init_random();
+ while (1) {
+ manage_request(target_domain);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>,
+ *
+ * Distributed freely under the terms of the GNU General Public License,
+ * version 2. See the file COPYING for licensing details
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ */
+
+#ifndef _WBNTLM_H_
+#define _WBNTLM_H_
+
+#include "config.h"
+#include "ntlmauth.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+/*************** CONFIGURATION ***************/
+#ifndef DEBUG
+#define DEBUG
+#endif
+
+/* the attempted entropy source. If it doesn't exist, random() is uesed */
+#define ENTROPY_SOURCE "/dev/urandom"
+
+/************* END CONFIGURATION *************/
+
+/* Debugging stuff */
+extern char *myname;
+static char *__foo;
+extern pid_t mypid;
+extern char debug_enabled;
+
+#ifdef DEBUG
+#define __DO_DEBUG 1
+#else
+#define __DO_DEBUG 0
+#endif
+
+#if defined(__GNUC__) || defined(__ICC) /* this is really a gcc-ism */
+#define warn(X...) fprintf(stderr,"%s[%d](%s:%d): ", myname, mypid, \
+ ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\
+ __LINE__);\
+ fprintf(stderr,X)
+#define debug(X...) if(__DO_DEBUG && debug_enabled) { warn(X); }
+#else /* __GNUC__ */
+static void
+debug(char *format,...)
+{
+}
+static void
+warn(char *format,...)
+{
+}
+#endif /* __GNUC__ */
+
+
+
+/* A couple of harmless helper macros */
+#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
+#if defined(__GNUC__) || defined (__ICC)
+#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); \
+ printf(X "\n",Y)
+#else
+/* no gcc, no debugging. varargs macros are a gcc extension */
+#define SEND2 printf
+#endif
+
+typedef enum {
+ YES,
+ NO,
+ DONTKNOW
+} tristate;
+
+#define CHALLENGE_LEN 8
+#define BUFFER_SIZE 2010
+
+#endif /* _WBNTLM_H_ */
--- /dev/null
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+
+ Winbind daemon for ntdom nss module
+
+ Copyright (C) Tim Potter 2000
+
+ 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_CONFIG_H
+#define _WINBIND_NSS_CONFIG_H
+
+/* Include header files from data in config.h file */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_UNIXSOCKET
+#include <sys/un.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <pwd.h>
+#include "samba_nss.h"
+
+/* Declarations for functions in winbind_nss.c
+ needed in winbind_nss_solaris.c (solaris wrapper to nss) */
+
+NSS_STATUS _nss_winbind_setpwent(void);
+NSS_STATUS _nss_winbind_endpwent(void);
+NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result,
+ char* buffer, size_t buflen, int* errnop);
+
+NSS_STATUS _nss_winbind_setgrent(void);
+NSS_STATUS _nss_winbind_endgrent(void);
+NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getgrnam_r(const char *name,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop);
+NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop);
+
+/* I'm trying really hard not to include anything from smb.h with the
+ result of some silly looking redeclaration of structures. */
+
+#ifndef _PSTRING
+#define _PSTRING
+#define PSTRING_LEN 1024
+#define FSTRING_LEN 256
+typedef char pstring[PSTRING_LEN];
+typedef char fstring[FSTRING_LEN];
+#endif
+
+#ifndef _BOOL
+#define _BOOL /* So we don't typedef BOOL again in vfs.h */
+#define False (0)
+#define True (1)
+#define Auto (2)
+typedef int BOOL;
+#endif
+
+#if !defined(uint32)
+#if (SIZEOF_INT == 4)
+#define uint32 unsigned int
+#elif (SIZEOF_LONG == 4)
+#define uint32 unsigned long
+#elif (SIZEOF_SHORT == 4)
+#define uint32 unsigned short
+#endif
+#endif
+
+#if !defined(uint16)
+#if (SIZEOF_SHORT == 4)
+#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;
+#else /* SIZEOF_SHORT != 4 */
+#define uint16 unsigned short
+#endif /* SIZEOF_SHORT != 4 */
+#endif
+
+#ifndef uint8
+#define uint8 unsigned char
+#endif
+
+/* zero a structure */
+#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
+
+/* zero a structure given a pointer to the structure */
+#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }
+
+/* Some systems (SCO) treat UNIX domain sockets as FIFOs */
+
+#ifndef S_IFSOCK
+#define S_IFSOCK S_IFIFO
+#endif
+
+#ifndef S_ISSOCK
+#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK)
+#endif
+
+#endif
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind daemon for ntdom nss module
+
+ Copyright (C) Tim Potter 2000
+
+ 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 SAFE_FREE
+#define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0)
+#endif
+
+#ifndef _WINBINDD_NTDOM_H
+#define _WINBINDD_NTDOM_H
+
+#define WINBINDD_SOCKET_NAME "pipe" /* Name of PF_UNIX socket */
+#define WINBINDD_SOCKET_DIR "/tmp/.winbindd" /* Name of PF_UNIX dir */
+
+#define WINBINDD_DOMAIN_ENV "WINBINDD_DOMAIN" /* Environment variables */
+#define WINBINDD_DONT_ENV "_NO_WINBINDD"
+
+/* Update this when you change the interface. */
+
+#define WINBIND_INTERFACE_VERSION 4
+
+/* Socket commands */
+
+enum winbindd_cmd {
+
+ WINBINDD_INTERFACE_VERSION, /* Always a well known value */
+
+ /* Get users and groups */
+
+ WINBINDD_GETPWNAM,
+ WINBINDD_GETPWUID,
+ WINBINDD_GETGRNAM,
+ WINBINDD_GETGRGID,
+ WINBINDD_GETGROUPS,
+
+ /* Enumerate users and groups */
+
+ WINBINDD_SETPWENT,
+ WINBINDD_ENDPWENT,
+ WINBINDD_GETPWENT,
+ WINBINDD_SETGRENT,
+ WINBINDD_ENDGRENT,
+ WINBINDD_GETGRENT,
+
+ /* PAM authenticate and password change */
+
+ WINBINDD_PAM_AUTH,
+ WINBINDD_PAM_AUTH_CRAP,
+ WINBINDD_PAM_CHAUTHTOK,
+
+ /* List various things */
+
+ WINBINDD_LIST_USERS, /* List w/o rid->id mapping */
+ WINBINDD_LIST_GROUPS, /* Ditto */
+ WINBINDD_LIST_TRUSTDOM,
+
+ /* SID conversion */
+
+ WINBINDD_LOOKUPSID,
+ WINBINDD_LOOKUPNAME,
+
+ /* Lookup functions */
+
+ WINBINDD_SID_TO_UID,
+ WINBINDD_SID_TO_GID,
+ WINBINDD_UID_TO_SID,
+ WINBINDD_GID_TO_SID,
+
+ /* Miscellaneous other stuff */
+
+ WINBINDD_CHECK_MACHACC, /* Check machine account pw works */
+ WINBINDD_PING, /* Just tell me winbind is running */
+ WINBINDD_INFO, /* Various bit of info. Currently just tidbits */
+ WINBINDD_DOMAIN_NAME, /* The domain this winbind server is a member of (lp_workgroup()) */
+
+ WINBINDD_SHOW_SEQUENCE, /* display sequence numbers of domains */
+
+ /* Placeholder for end of cmd list */
+
+ WINBINDD_NUM_CMDS
+};
+
+/* Winbind request structure */
+
+struct winbindd_request {
+ uint32 length;
+ enum winbindd_cmd cmd; /* Winbindd command to execute */
+ pid_t pid; /* pid of calling process */
+
+ union {
+ fstring username; /* getpwnam */
+ fstring groupname; /* getgrnam */
+ uid_t uid; /* getpwuid, uid_to_sid */
+ gid_t gid; /* getgrgid, gid_to_sid */
+ struct {
+ fstring user;
+ fstring pass;
+ } auth; /* pam_winbind auth module */
+ struct {
+ unsigned char chal[8];
+ fstring user;
+ fstring domain;
+ fstring lm_resp;
+ uint16 lm_resp_len;
+ fstring nt_resp;
+ uint16 nt_resp_len;
+ } auth_crap;
+ struct {
+ fstring user;
+ fstring oldpass;
+ fstring newpass;
+ } chauthtok; /* pam_winbind passwd module */
+ fstring sid; /* lookupsid, sid_to_[ug]id */
+ struct {
+ fstring dom_name; /* lookupname */
+ fstring name;
+ } name;
+ uint32 num_entries; /* getpwent, getgrent */
+ } data;
+ fstring domain; /* {set,get,end}{pw,gr}ent() */
+};
+
+/* Response values */
+
+enum winbindd_result {
+ WINBINDD_ERROR,
+ WINBINDD_OK
+};
+
+/* Winbind response structure */
+
+struct winbindd_response {
+
+ /* Header information */
+
+ uint32 length; /* Length of response */
+ enum winbindd_result result; /* Result code */
+
+ /* Fixed length return data */
+
+ union {
+ int interface_version; /* Try to ensure this is always in the same spot... */
+
+ /* getpwnam, getpwuid */
+
+ struct winbindd_pw {
+ fstring pw_name;
+ fstring pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ fstring pw_gecos;
+ fstring pw_dir;
+ fstring pw_shell;
+ } pw;
+
+ /* getgrnam, getgrgid */
+
+ struct winbindd_gr {
+ fstring gr_name;
+ fstring gr_passwd;
+ gid_t gr_gid;
+ int num_gr_mem;
+ int gr_mem_ofs; /* offset to group membership */
+ } gr;
+
+ uint32 num_entries; /* getpwent, getgrent */
+ struct winbindd_sid {
+ fstring sid; /* lookupname, [ug]id_to_sid */
+ int type;
+ } sid;
+ struct winbindd_name {
+ fstring dom_name; /* lookupsid */
+ fstring name;
+ int type;
+ } name;
+ uid_t uid; /* sid_to_uid */
+ gid_t gid; /* sid_to_gid */
+ struct winbindd_info {
+ char winbind_separator;
+ fstring samba_version;
+ } info;
+ fstring domain_name;
+
+ struct auth_reply {
+ uint32 nt_status;
+ fstring nt_status_string;
+ fstring error_string;
+ int pam_error;
+ } auth;
+ } data;
+
+ /* Variable length return data */
+
+ void *extra_data; /* getgrnam, getgrgid, getgrent */
+};
+
+#endif