From: hno <> Date: Mon, 8 Jul 2002 00:18:11 +0000 (+0000) Subject: winbind based external_acl group helper by Guido X-Git-Tag: SQUID_3_0_PRE1~913 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4402cd0fb26dd47486975c39fb3035da7a76b283;p=thirdparty%2Fsquid.git winbind based external_acl group helper by Guido --- diff --git a/CREDITS b/CREDITS index 3a6b4a935f..44cc8bec10 100644 --- a/CREDITS +++ b/CREDITS @@ -1,4 +1,4 @@ -$Id: CREDITS,v 1.7 2002/07/05 09:20:56 hno Exp $ +$Id: CREDITS,v 1.8 2002/07/07 18:18:11 hno Exp $ ============================================================================== @@ -312,3 +312,28 @@ helpers/external_acl/wbinfo_group/wbinfo_group.pl be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +============================================================================== + +helpers/external_acl/winbind_group/ + + This is a helper for the external ACL interface for Squid Cache + Copyright (C) 2002 Guido Serassio + Based on previous work of Rodrigo Albani de Campos + + This program 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; either version 2 of the License, or + (at your option) any later version. + + includes code contributed by others + + 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. + diff --git a/configure.in b/configure.in index 07d51f36ee..d27603ed02 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Configuration input file for Squid dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.276 2002/07/06 12:23:12 hno Exp $ +dnl $Id: configure.in,v 1.277 2002/07/07 18:18:11 hno Exp $ dnl dnl dnl @@ -11,7 +11,7 @@ AC_INIT(src/main.c) AC_CONFIG_AUX_DIR(cfgaux) AM_INIT_AUTOMAKE(squid, 2.6-DEVEL) AM_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.276 $)dnl +AC_REVISION($Revision: 1.277 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE @@ -2304,4 +2304,5 @@ AC_OUTPUT([\ helpers/external_acl/ldap_group/Makefile \ helpers/external_acl/unix_group/Makefile \ helpers/external_acl/wbinfo_group/Makefile \ + helpers/external_acl/winbind_group/Makefile \ ]) diff --git a/helpers/external_acl/Makefile.am b/helpers/external_acl/Makefile.am index 339e55266c..e57ed62aeb 100644 --- a/helpers/external_acl/Makefile.am +++ b/helpers/external_acl/Makefile.am @@ -1,7 +1,7 @@ # Makefile for storage modules in the Squid Object Cache server # -# $Id: Makefile.am,v 1.1 2002/07/06 12:23:13 hno Exp $ +# $Id: Makefile.am,v 1.2 2002/07/07 18:18:12 hno Exp $ # -DIST_SUBDIRS = ip_user ldap_group unix_group wbinfo_group +DIST_SUBDIRS = ip_user ldap_group unix_group wbinfo_group winbind_group SUBDIRS = @EXTERNAL_ACL_HELPERS@ diff --git a/helpers/external_acl/winbind_group/Makefile.am b/helpers/external_acl/winbind_group/Makefile.am new file mode 100755 index 0000000000..7ab9ba23c1 --- /dev/null +++ b/helpers/external_acl/winbind_group/Makefile.am @@ -0,0 +1,11 @@ +# +# Makefile for the wb_group external_acl helper +# +# $Id: Makefile.am,v 1.1 2002/07/07 18:18:12 hno Exp $ +# + +libexec_PROGRAMS = wb_group +wb_auth_SOURCES = wb_check_group.c wb_common.c samba_nss.h winbindd_nss.h wbntlm.h winbind_nss_config.h +INCLUDES = -I. -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/src +LDADD = -L$(top_builddir)/lib -lmiscutil -lntlmauth $(XTRA_LIBS) diff --git a/helpers/external_acl/winbind_group/readme.txt b/helpers/external_acl/winbind_group/readme.txt new file mode 100755 index 0000000000..d95a197d8e --- /dev/null +++ b/helpers/external_acl/winbind_group/readme.txt @@ -0,0 +1,66 @@ +This is the README file for wb_group, an external +helper fo the External ACL Scheme for Squid based on +Samba Winbindd from Samba 2.2.4 or greater. + + +This helper must be used in with an authentication scheme, tipically +basic or NTLM, based on Windows NT/2000 domain users. +It reads two new line terminated arguments from the standard input +(the domain username and group) and tries to match it against +the domain global groups membership of the specified username. + +For Winbindd configuration, look the Squid winbind authenticators +instructions. + + +============== +Program Syntax +============== + +wb_group [-d] + +-d enable debug mode + + +================ +squid.conf usage +================ + +external_acl_type NT_global_group %LOGIN /usr/local/squid/libexec/wb_group + +acl ProxyUsers external NT_global_group ProxyUsers +acl password proxy_auth REQUIRED + +http_access allow password ProxyUsers +http_access deny all + +In the previous example all validated NT users member of ProxyUsers Global +domain group are allowed to use the cache. + +Groups with spaces in name must be quoted, for example "Domain Users" + +NOTE: the group name comparation is case sensitive, so group name +must be specified with same case as in the NT/2000 Domain. + +Refer to Squid documentation for the more details on squid.conf. + + +======= +Testing +======= + +I strongly urge that wb_group is tested prior to being used in a +production environment. It may behave differently on different platforms. +To test it, run it from the command line. Enter username and group +pairs separated by a space (username must entered with domain\\username +syntax). Press ENTER to get an OK or ERR message. +Make sure pressing behaves the same as a carriage return. +Make sure pressing aborts the program. + +Test that entering no details does not result in an OK or ERR message. +Test that entering an invalid username and group results in an ERR message. +Test that entering an valid username and group results in an OK message. + +-- +Serassio Guido +squidnt@serassio.it diff --git a/helpers/external_acl/winbind_group/samba_nss.h b/helpers/external_acl/winbind_group/samba_nss.h new file mode 100755 index 0000000000..8bf5d9a56c --- /dev/null +++ b/helpers/external_acl/winbind_group/samba_nss.h @@ -0,0 +1,105 @@ +#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 +#include +#include + +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 + +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 + +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 + +#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 */ diff --git a/helpers/external_acl/winbind_group/wb_check_group.c b/helpers/external_acl/winbind_group/wb_check_group.c new file mode 100755 index 0000000000..8ec74b95ff --- /dev/null +++ b/helpers/external_acl/winbind_group/wb_check_group.c @@ -0,0 +1,254 @@ +/* + * $Id: wb_check_group.c,v 1.1 2002/07/07 18:18:12 hno Exp $ + * + * This is a helper for the external ACL interface for Squid Cache + * Copyright (C) 2002 Guido Serassio + * Based on previous work of Rodrigo Albani de Campos + * + * It reads STDIN looking for a username that matches a NT/2000 global + * Domain group. Requires Samba 2.2.4 or later with Winbindd. + * Returns `OK' if the user belongs to the group or `ERR' otherwise, as + * described on http://devel.squid-cache.org/external_acl/config.html + * To compile this program, use: + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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" + +#include +#include +#include +#include + +#include "winbind_nss_config.h" +#include "winbindd_nss.h" + +#define BUFSIZE 8192 /* the stdin buffer size */ +char debug_enabled=0; +char *myname; +pid_t mypid; + +NSS_STATUS winbindd_request(int req_type, + struct winbindd_request *request, + struct winbindd_response *response); + +static char * +strwordtok(char *buf, char **t) +{ + unsigned char *word = NULL; + unsigned char *p = (unsigned char *) buf; + unsigned char *d; + unsigned char ch; + int quoted = 0; + if (!p) + p = (unsigned char *) *t; + if (!p) + goto error; + while (*p && isspace(*p)) + p++; + if (!*p) + goto error; + word = d = p; + while ((ch = *p)) { + switch (ch) { + case '\\': + p++; + *d++ = ch = *p; + if (ch) + p++; + break; + case '"': + quoted = !quoted; + p++; + default: + if (!quoted && isspace(*p)) { + p++; + goto done; + } + *d++ = *p++; + break; + } + } + done: + *d++ = '\0'; + error: + *t = (char *) p; + return (char *) word; +} + + + +/* Convert sid to string */ + +char * wbinfo_lookupsid(char * group, char *sid) +{ + struct winbindd_request request; + struct winbindd_response response; + + memset(&request,0,sizeof(struct winbindd_request)); + memset(&response,0,sizeof(struct winbindd_response)); + + /* Send off request */ + + strncpy(request.data.sid, sid,sizeof(fstring)-1); + + if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) != + NSS_STATUS_SUCCESS) + return NULL; + + /* Display response */ + + strcpy(group,response.data.name.name); + return group; +} + + +/* Convert gid to sid */ + +char * wbinfo_gid_to_sid(char * sid, gid_t gid) +{ + struct winbindd_request request; + struct winbindd_response response; + + memset(&request,0,sizeof(struct winbindd_request)); + memset(&response,0,sizeof(struct winbindd_response)); + + /* Send request */ + + request.data.gid = gid; + + if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) != + NSS_STATUS_SUCCESS) + return NULL; + + /* Display response */ + + strcpy(sid, response.data.sid.sid); + + return sid; +} + +/* returns 1 on success, 0 on failure */ +int +Valid_Group(char *UserName, char *UserGroup) +{ + struct winbindd_request request; + struct winbindd_response response; + NSS_STATUS result; + int i; + char sid[FSTRING_LEN]; + char group[FSTRING_LEN]; + int match = 0; + + memset(&request,0,sizeof(struct winbindd_request)); + memset(&response,0,sizeof(struct winbindd_response)); + + /* Send request */ + + strncpy(request.data.username,UserName,sizeof(fstring)-1); + + result = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + + if (result != NSS_STATUS_SUCCESS) + return match; + + for (i = 0; i < response.data.num_entries; i++) { + if ((wbinfo_gid_to_sid(sid, (int)((gid_t *)response.extra_data)[i])) != NULL) { + debug("SID: %s\n", sid); + if (wbinfo_lookupsid(group,sid) == NULL) + break; + debug("Windows group: %s, Squid group: %s\n", group, UserGroup); + if (strcmp(group,UserGroup) == 0) { + match = 1; + break; + } + } else { + return match; + } + } + SAFE_FREE(response.extra_data); + + return match; +} + +void +process_options(int argc, char *argv[]) +{ + int opt; + + 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 */ + } + } + return; +} + +int +main (int argc, char *argv[]) +{ + char *p, *t; + char buf[BUFSIZE]; + char *username; + char *group; + + if (argc > 0) { /* should always be true */ + myname=strrchr(argv[0],'/'); + if (myname==NULL) + myname=argv[0]; + } else { + myname="(unknown)"; + } + mypid=getpid(); + + /* make standard output line buffered */ + setvbuf (stdout, NULL, _IOLBF, 0); + + /* Check Command Line */ + process_options(argc, argv); + + debug("External ACL winbindd group helper build " __DATE__ ", " __TIME__ + " starting up...\n"); + + /* Main Loop */ + while (fgets (buf, BUFSIZE, stdin)) + { + + if ((p = strchr(buf, '\n')) != NULL) + *p = '\0'; /* strip \n */ + if ((p = strchr(buf, '\r')) != NULL) + *p = '\0'; /* strip \r */ + + debug("Got '%s' from Squid (length: %d).\n",buf,sizeof(buf)); + + username = strwordtok(buf, &t); + group = strwordtok(NULL, &t); + + if (Valid_Group(username, group)) { + printf ("OK\n"); + } else { + printf ("ERR\n"); + } + } + return 0; +} diff --git a/helpers/external_acl/winbind_group/wb_common.c b/helpers/external_acl/winbind_group/wb_common.c new file mode 100755 index 0000000000..91aeb79621 --- /dev/null +++ b/helpers/external_acl/winbind_group/wb_common.c @@ -0,0 +1,398 @@ +/* + 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); +} diff --git a/helpers/external_acl/winbind_group/wbntlm.h b/helpers/external_acl/winbind_group/wbntlm.h new file mode 100755 index 0000000000..d4689b2810 --- /dev/null +++ b/helpers/external_acl/winbind_group/wbntlm.h @@ -0,0 +1,90 @@ +/* + * (C) 2000 Francesco Chemolli , + * + * 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 +#include +#include +#include + + +/*************** 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_ */ diff --git a/helpers/external_acl/winbind_group/winbind_nss_config.h b/helpers/external_acl/winbind_group/winbind_nss_config.h new file mode 100755 index 0000000000..2f301f7261 --- /dev/null +++ b/helpers/external_acl/winbind_group/winbind_nss_config.h @@ -0,0 +1,148 @@ +/* + 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 + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_UNIXSOCKET +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_GRP_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#include +#include +#include +#include +#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 diff --git a/helpers/external_acl/winbind_group/winbindd_nss.h b/helpers/external_acl/winbind_group/winbindd_nss.h new file mode 100755 index 0000000000..023d72306b --- /dev/null +++ b/helpers/external_acl/winbind_group/winbindd_nss.h @@ -0,0 +1,224 @@ +/* + 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 */ + + /* WINS commands */ + + WINBINDD_WINS_BYIP, + WINBINDD_WINS_BYNAME, + + /* 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 winsreq; /* WINS request */ + 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... */ + + fstring winsresp; /* WINS response */ + + /* 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