-#ifndef _NSSWITCH_NSS_H\r
-#define _NSSWITCH_NSS_H\r
-/* \r
- Unix SMB/Netbios implementation.\r
- Version 2.0\r
-\r
- a common place to work out how to define NSS_STATUS on various\r
- platforms\r
-\r
- Copyright (C) Tim Potter 2000\r
- \r
- This library is free software; you can redistribute it and/or\r
- modify it under the terms of the GNU Library General Public\r
- License as published by the Free Software Foundation; either\r
- version 2 of the License, or (at your option) any later version.\r
- \r
- This library is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- Library General Public License for more details.\r
- \r
- You should have received a copy of the GNU Library General Public\r
- License along with this library; if not, write to the\r
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
- Boston, MA 02111-1307, USA. \r
-*/\r
-\r
-#ifdef HAVE_NSS_COMMON_H\r
-\r
-/* Sun Solaris */\r
-\r
-#include <nss_common.h>\r
-#include <nss_dbdefs.h>\r
-#include <nsswitch.h>\r
-\r
-typedef nss_status_t NSS_STATUS;\r
-\r
-#define NSS_STATUS_SUCCESS NSS_SUCCESS\r
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND\r
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL\r
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN\r
-\r
-#elif HAVE_NSS_H\r
-\r
-/* GNU */\r
-\r
-#include <nss.h>\r
-\r
-typedef enum nss_status NSS_STATUS;\r
-\r
-#elif HAVE_NS_API_H\r
-\r
-/* SGI IRIX */\r
-\r
-/* following required to prevent warnings of double definition\r
- * of datum from ns_api.h\r
-*/\r
-#ifdef DATUM\r
-#define _DATUM_DEFINED\r
-#endif\r
-\r
-#include <ns_api.h>\r
-\r
-typedef enum\r
-{\r
- NSS_STATUS_SUCCESS=NS_SUCCESS,\r
- NSS_STATUS_NOTFOUND=NS_NOTFOUND,\r
- NSS_STATUS_UNAVAIL=NS_UNAVAIL,\r
- NSS_STATUS_TRYAGAIN=NS_TRYAGAIN\r
-} NSS_STATUS;\r
-\r
-#define NSD_MEM_STATIC 0\r
-#define NSD_MEM_VOLATILE 1\r
-#define NSD_MEM_DYNAMIC 2\r
-\r
-#elif defined(HPUX)\r
-/* HP-UX 11 */\r
-\r
-#include "nsswitch/hp_nss_common.h"\r
-#include "nsswitch/hp_nss_dbdefs.h"\r
-#include <nsswitch.h>\r
-\r
-#ifndef _HAVE_TYPEDEF_NSS_STATUS\r
-#define _HAVE_TYPEDEF_NSS_STATUS\r
-typedef nss_status_t NSS_STATUS;\r
-\r
-#define NSS_STATUS_SUCCESS NSS_SUCCESS\r
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND\r
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL\r
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN\r
-#endif /* HPUX */\r
-\r
-#else /* Nothing's defined. Neither gnu nor sun nor hp */\r
-\r
-typedef enum\r
-{\r
- NSS_STATUS_SUCCESS=0,\r
- NSS_STATUS_NOTFOUND=1,\r
- NSS_STATUS_UNAVAIL=2,\r
- NSS_STATUS_TRYAGAIN=3\r
-} NSS_STATUS;\r
-\r
-#endif\r
-\r
-#endif /* _NSSWITCH_NSS_H */\r
+#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 */
-/* \r
- Unix SMB/Netbios implementation.\r
- Version 2.0\r
-\r
- winbind client common code\r
-\r
- Copyright (C) Tim Potter 2000\r
- Copyright (C) Andrew Tridgell 2000\r
- \r
- This library is free software; you can redistribute it and/or\r
- modify it under the terms of the GNU Library General Public\r
- License as published by the Free Software Foundation; either\r
- version 2 of the License, or (at your option) any later version.\r
- \r
- This library is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- Library General Public License for more details.\r
- \r
- You should have received a copy of the GNU Library General Public\r
- License along with this library; if not, write to the\r
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
- Boston, MA 02111-1307, USA. \r
-*/\r
-\r
-#include "winbind_nss_config.h"\r
-#include "winbindd_nss.h"\r
-#include "config.h"\r
-\r
-\r
-/* Global variables. These are effectively the client state information */\r
-\r
-int winbindd_fd = -1; /* fd for winbindd socket */\r
-static char *excluded_domain;\r
-\r
-/* Free a response structure */\r
-\r
-void free_response(struct winbindd_response *response)\r
-{\r
- /* Free any allocated extra_data */\r
-\r
- if (response)\r
- SAFE_FREE(response->extra_data);\r
-}\r
-\r
-/*\r
- smbd needs to be able to exclude lookups for its own domain\r
-*/\r
-void winbind_exclude_domain(const char *domain)\r
-{\r
- SAFE_FREE(excluded_domain);\r
- excluded_domain = strdup(domain);\r
-}\r
-\r
-\r
-/* Initialise a request structure */\r
-\r
-void init_request(struct winbindd_request *request, int request_type)\r
-{\r
- static char *domain_env;\r
- static BOOL initialised;\r
-\r
- request->length = sizeof(struct winbindd_request);\r
-\r
- request->cmd = (enum winbindd_cmd)request_type;\r
- request->pid = getpid();\r
- request->domain[0] = '\0';\r
-\r
- if (!initialised) {\r
- initialised = True;\r
- domain_env = getenv(WINBINDD_DOMAIN_ENV);\r
- }\r
-\r
- if (domain_env) {\r
- strncpy(request->domain, domain_env,\r
- sizeof(request->domain) - 1);\r
- request->domain[sizeof(request->domain) - 1] = '\0';\r
- }\r
-}\r
-\r
-/* Initialise a response structure */\r
-\r
-void init_response(struct winbindd_response *response)\r
-{\r
- /* Initialise return value */\r
-\r
- response->result = WINBINDD_ERROR;\r
-}\r
-\r
-/* Close established socket */\r
-\r
-void close_sock(void)\r
-{\r
- if (winbindd_fd != -1) {\r
- close(winbindd_fd);\r
- winbindd_fd = -1;\r
- }\r
-}\r
-\r
-/* Connect to winbindd socket */\r
-\r
-int winbind_open_pipe_sock(void)\r
-{\r
- struct sockaddr_un sunaddr;\r
- static pid_t our_pid;\r
- struct stat st;\r
- pstring path;\r
- \r
- if (our_pid != getpid()) {\r
- close_sock();\r
- our_pid = getpid();\r
- }\r
- \r
- if (winbindd_fd != -1) {\r
- return winbindd_fd;\r
- }\r
- \r
- /* Check permissions on unix socket directory */\r
- \r
- if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {\r
- return -1;\r
- }\r
- \r
- if (!S_ISDIR(st.st_mode) || \r
- (st.st_uid != 0 && st.st_uid != geteuid())) {\r
- return -1;\r
- }\r
- \r
- /* Connect to socket */\r
- \r
- strncpy(path, WINBINDD_SOCKET_DIR, sizeof(path) - 1);\r
- path[sizeof(path) - 1] = '\0';\r
- \r
- strncat(path, "/", sizeof(path) - 1);\r
- path[sizeof(path) - 1] = '\0';\r
- \r
- strncat(path, WINBINDD_SOCKET_NAME, sizeof(path) - 1);\r
- path[sizeof(path) - 1] = '\0';\r
- \r
- ZERO_STRUCT(sunaddr);\r
- sunaddr.sun_family = AF_UNIX;\r
- strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path) - 1);\r
- \r
- /* If socket file doesn't exist, don't bother trying to connect\r
- with retry. This is an attempt to make the system usable when\r
- the winbindd daemon is not running. */\r
-\r
- if (lstat(path, &st) == -1) {\r
- return -1;\r
- }\r
- \r
- /* Check permissions on unix socket file */\r
- \r
- if (!S_ISSOCK(st.st_mode) || \r
- (st.st_uid != 0 && st.st_uid != geteuid())) {\r
- return -1;\r
- }\r
- \r
- /* Connect to socket */\r
- \r
- if ((winbindd_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {\r
- return -1;\r
- }\r
- \r
- if (connect(winbindd_fd, (struct sockaddr *)&sunaddr, \r
- sizeof(sunaddr)) == -1) {\r
- close_sock();\r
- return -1;\r
- }\r
- \r
- return winbindd_fd;\r
-}\r
-\r
-/* Write data to winbindd socket with timeout */\r
-\r
-int write_sock(void *buffer, int count)\r
-{\r
- int result, nwritten;\r
- \r
- /* Open connection to winbind daemon */\r
- \r
- restart:\r
- \r
- if (winbind_open_pipe_sock() == -1) {\r
- return -1;\r
- }\r
- \r
- /* Write data to socket */\r
- \r
- nwritten = 0;\r
- \r
- while(nwritten < count) {\r
- struct timeval tv;\r
- fd_set r_fds;\r
- \r
- /* Catch pipe close on other end by checking if a read()\r
- call would not block by calling select(). */\r
-\r
- FD_ZERO(&r_fds);\r
- FD_SET(winbindd_fd, &r_fds);\r
- ZERO_STRUCT(tv);\r
- \r
- if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {\r
- close_sock();\r
- return -1; /* Select error */\r
- }\r
- \r
- /* Write should be OK if fd not available for reading */\r
- \r
- if (!FD_ISSET(winbindd_fd, &r_fds)) {\r
- \r
- /* Do the write */\r
- \r
- result = write(winbindd_fd,\r
- (char *)buffer + nwritten, \r
- count - nwritten);\r
- \r
- if ((result == -1) || (result == 0)) {\r
- \r
- /* Write failed */\r
- \r
- close_sock();\r
- return -1;\r
- }\r
- \r
- nwritten += result;\r
- \r
- } else {\r
- \r
- /* Pipe has closed on remote end */\r
- \r
- close_sock();\r
- goto restart;\r
- }\r
- }\r
- \r
- return nwritten;\r
-}\r
-\r
-/* Read data from winbindd socket with timeout */\r
-\r
-static int read_sock(void *buffer, int count)\r
-{\r
- int result = 0, nread = 0;\r
-\r
- /* Read data from socket */\r
- \r
- while(nread < count) {\r
- \r
- result = read(winbindd_fd, (char *)buffer + nread, \r
- count - nread);\r
- \r
- if ((result == -1) || (result == 0)) {\r
- \r
- /* Read failed. I think the only useful thing we\r
- can do here is just return -1 and fail since the\r
- transaction has failed half way through. */\r
- \r
- close_sock();\r
- return -1;\r
- }\r
- \r
- nread += result;\r
- }\r
- \r
- return result;\r
-}\r
-\r
-/* Read reply */\r
-\r
-int read_reply(struct winbindd_response *response)\r
-{\r
- int result1, result2 = 0;\r
-\r
- if (!response) {\r
- return -1;\r
- }\r
- \r
- /* Read fixed length response */\r
- \r
- if ((result1 = read_sock(response, sizeof(struct winbindd_response)))\r
- == -1) {\r
- \r
- return -1;\r
- }\r
- \r
- /* We actually send the pointer value of the extra_data field from\r
- the server. This has no meaning in the client's address space\r
- so we clear it out. */\r
-\r
- response->extra_data = NULL;\r
-\r
- /* Read variable length response */\r
- \r
- if (response->length > sizeof(struct winbindd_response)) {\r
- int extra_data_len = response->length - \r
- sizeof(struct winbindd_response);\r
- \r
- /* Mallocate memory for extra data */\r
- \r
- if (!(response->extra_data = malloc(extra_data_len))) {\r
- return -1;\r
- }\r
- \r
- if ((result2 = read_sock(response->extra_data, extra_data_len))\r
- == -1) {\r
- free_response(response);\r
- return -1;\r
- }\r
- }\r
- \r
- /* Return total amount of data read */\r
- \r
- return result1 + result2;\r
-}\r
-\r
-/* \r
- * send simple types of requests \r
- */\r
-\r
-NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)\r
-{\r
- struct winbindd_request lrequest;\r
-\r
- /* Check for our tricky environment variable */\r
-\r
- if (getenv(WINBINDD_DONT_ENV)) {\r
- return NSS_STATUS_NOTFOUND;\r
- }\r
-\r
- /* smbd may have excluded this domain */\r
- if (excluded_domain && \r
- strcasecmp(excluded_domain, request->domain) == 0) {\r
- return NSS_STATUS_NOTFOUND;\r
- }\r
-\r
- if (!request) {\r
- ZERO_STRUCT(lrequest);\r
- request = &lrequest;\r
- }\r
- \r
- /* Fill in request and send down pipe */\r
-\r
- init_request(request, req_type);\r
- \r
- if (write_sock(request, sizeof(*request)) == -1) {\r
- return NSS_STATUS_UNAVAIL;\r
- }\r
- \r
- return NSS_STATUS_SUCCESS;\r
-}\r
-\r
-/*\r
- * Get results from winbindd request\r
- */\r
-\r
-NSS_STATUS winbindd_get_response(struct winbindd_response *response)\r
-{\r
- struct winbindd_response lresponse;\r
-\r
- if (!response) {\r
- ZERO_STRUCT(lresponse);\r
- response = &lresponse;\r
- }\r
-\r
- init_response(response);\r
-\r
- /* Wait for reply */\r
- if (read_reply(response) == -1) {\r
- return NSS_STATUS_UNAVAIL;\r
- }\r
-\r
- /* Throw away extra data if client didn't request it */\r
- if (response == &lresponse) {\r
- free_response(response);\r
- }\r
-\r
- /* Copy reply data from socket */\r
- if (response->result != WINBINDD_OK) {\r
- return NSS_STATUS_NOTFOUND;\r
- }\r
- \r
- return NSS_STATUS_SUCCESS;\r
-}\r
-\r
-/* Handle simple types of requests */\r
-\r
-NSS_STATUS winbindd_request(int req_type, \r
- struct winbindd_request *request,\r
- struct winbindd_response *response)\r
-{\r
- NSS_STATUS status;\r
-\r
- status = winbindd_send_request(req_type, request);\r
- if (status != NSS_STATUS_SUCCESS) \r
- return(status);\r
- return winbindd_get_response(response);\r
-}\r
+/*
+ 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);
+}
-/*\r
- * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>,\r
- *\r
- * Distributed freely under the terms of the GNU General Public License,\r
- * version 2. See the file COPYING for licensing details\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- \r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.\r
- */\r
-\r
-#ifndef _WBNTLM_H_\r
-#define _WBNTLM_H_\r
-\r
-#include "config.h"\r
-#include "ntlmauth.h"\r
-#include <sys/types.h>\r
-#include <unistd.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-\r
-\r
-/*************** CONFIGURATION ***************/\r
-#ifndef DEBUG\r
-#define DEBUG\r
-#endif\r
-\r
-/* the attempted entropy source. If it doesn't exist, random() is uesed */\r
-#define ENTROPY_SOURCE "/dev/urandom"\r
-\r
-#define DOMAIN "GCSINT" /* TODO: fix ntlm_make_challenge */\r
-\r
-/************* END CONFIGURATION *************/\r
-\r
-/* Debugging stuff */\r
-extern char *myname;\r
-static char *__foo;\r
-extern pid_t mypid;\r
-extern char debug_enabled;\r
-\r
-#ifdef DEBUG\r
-#define __DO_DEBUG 1\r
-#else\r
-#define __DO_DEBUG 0\r
-#endif\r
-\r
-#ifdef __GNUC__ /* this is really a gcc-ism */\r
-#define warn(X...) fprintf(stderr,"%s[%d](%s:%d): ", myname, mypid, \\r
- ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\\r
- __LINE__);\\r
- fprintf(stderr,X)\r
-#define debug(X...) if(__DO_DEBUG && debug_enabled) { warn(X); }\r
-#else /* __GNUC__ */\r
-static void\r
-debug(char *format,...)\r
-{\r
-}\r
-static void\r
-warn(char *format,...)\r
-{\r
-}\r
-#endif /* __GNUC__ */\r
-\r
-\r
-\r
-/* A couple of harmless helper macros */\r
-#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");\r
-#ifdef __GNUC__\r
-#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); \\r
- printf(X "\n",Y)\r
-#else\r
-/* no gcc, no debugging. varargs macros are a gcc extension */\r
-#define SEND2 printf\r
-#endif\r
-\r
-typedef enum {\r
- YES,\r
- NO,\r
- DONTKNOW\r
-} tristate;\r
-\r
-#define CHALLENGE_LEN 8\r
-#define BUFFER_SIZE 2010\r
-\r
-#endif /* _WBNTLM_H_ */\r
+/*
+ * (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_ */
-/* \r
- Unix SMB/Netbios implementation.\r
- Version 2.0\r
-\r
- Winbind daemon for ntdom nss module\r
-\r
- Copyright (C) Tim Potter 2000\r
- \r
- This library is free software; you can redistribute it and/or\r
- modify it under the terms of the GNU Library General Public\r
- License as published by the Free Software Foundation; either\r
- version 2 of the License, or (at your option) any later version.\r
- \r
- This library is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- Library General Public License for more details.\r
- \r
- You should have received a copy of the GNU Library General Public\r
- License along with this library; if not, write to the\r
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
- Boston, MA 02111-1307, USA. \r
-*/\r
-\r
-#ifndef _WINBIND_NSS_CONFIG_H\r
-#define _WINBIND_NSS_CONFIG_H\r
-\r
-/* Include header files from data in config.h file */\r
-\r
-#include "config.h"\r
-\r
-#include <stdio.h>\r
-\r
-#ifdef HAVE_STDLIB_H\r
-#include <stdlib.h>\r
-#endif\r
-\r
-#ifdef HAVE_UNISTD_H\r
-#include <unistd.h>\r
-#endif\r
-\r
-#ifdef HAVE_SYS_SOCKET_H\r
-#include <sys/socket.h>\r
-#endif\r
-\r
-#ifdef HAVE_UNIXSOCKET\r
-#include <sys/un.h>\r
-#endif\r
-\r
-#ifdef HAVE_SYS_TIME_H\r
-#include <sys/time.h>\r
-#endif\r
-\r
-#ifdef HAVE_GRP_H\r
-#include <grp.h>\r
-#endif\r
-\r
-#ifdef HAVE_STRING_H\r
-#include <string.h>\r
-#endif\r
-\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <errno.h>\r
-#include <pwd.h>\r
-#include "samba_nss.h"\r
-\r
-/* Declarations for functions in winbind_nss.c\r
- needed in winbind_nss_solaris.c (solaris wrapper to nss) */\r
-\r
-NSS_STATUS _nss_winbind_setpwent(void);\r
-NSS_STATUS _nss_winbind_endpwent(void);\r
-NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer,\r
- size_t buflen, int* errnop);\r
-NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer,\r
- size_t buflen, int* errnop);\r
-NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result,\r
- char* buffer, size_t buflen, int* errnop);\r
-\r
-NSS_STATUS _nss_winbind_setgrent(void);\r
-NSS_STATUS _nss_winbind_endgrent(void);\r
-NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer,\r
- size_t buflen, int* errnop);\r
-NSS_STATUS _nss_winbind_getgrnam_r(const char *name,\r
- struct group *result, char *buffer,\r
- size_t buflen, int *errnop);\r
-NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,\r
- struct group *result, char *buffer,\r
- size_t buflen, int *errnop);\r
-\r
-/* I'm trying really hard not to include anything from smb.h with the\r
- result of some silly looking redeclaration of structures. */\r
-\r
-#ifndef _PSTRING\r
-#define _PSTRING\r
-#define PSTRING_LEN 1024\r
-#define FSTRING_LEN 256\r
-typedef char pstring[PSTRING_LEN];\r
-typedef char fstring[FSTRING_LEN];\r
-#endif\r
-\r
-#ifndef _BOOL\r
-#define _BOOL /* So we don't typedef BOOL again in vfs.h */\r
-#define False (0)\r
-#define True (1)\r
-#define Auto (2)\r
-typedef int BOOL;\r
-#endif\r
-\r
-#if !defined(uint32)\r
-#if (SIZEOF_INT == 4)\r
-#define uint32 unsigned int\r
-#elif (SIZEOF_LONG == 4)\r
-#define uint32 unsigned long\r
-#elif (SIZEOF_SHORT == 4)\r
-#define uint32 unsigned short\r
-#endif\r
-#endif\r
-\r
-#if !defined(uint16)\r
-#if (SIZEOF_SHORT == 4)\r
-#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;\r
-#else /* SIZEOF_SHORT != 4 */\r
-#define uint16 unsigned short\r
-#endif /* SIZEOF_SHORT != 4 */\r
-#endif\r
-\r
-#ifndef uint8\r
-#define uint8 unsigned char\r
-#endif\r
-\r
-/* zero a structure */\r
-#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))\r
-\r
-/* zero a structure given a pointer to the structure */\r
-#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }\r
- \r
-/* Some systems (SCO) treat UNIX domain sockets as FIFOs */\r
-\r
-#ifndef S_IFSOCK\r
-#define S_IFSOCK S_IFIFO\r
-#endif\r
-\r
-#ifndef S_ISSOCK\r
-#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK)\r
-#endif\r
-\r
-#endif\r
+/*
+ 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