Sorry if this is not the right forum, but the documents on the website kind
of implied I should send this to the list.

I needed to get wins resolution added on Solaris to nsswitch specifically
for gethostbyname.  The problem was that libnss_wins.so didn't include the
solaris wrapper and that libnss_winbind.so didn't include gethostbyname.
Here is a patch off of 2.2.7a that solves both issues (I'm not sure about
the #if SUN).  

The patch to libnss_wins.so is relatively straightforward; it just adds the
required constructor for solaris to nsswitch/wins.c.
The patch to libnss_winbind.so is not so straightforward, mostly because the
implementation of  _nss_winbind_gethostname_r doesn't appear to work on
linux.  I only have darwin and solaris, I apologize.  
It also seems that gethostname was omitted "on purpose" from winbind, but
that may just be a difference in timing between winbindd and libnss.

Thanks,
-Steven

diff -r -c samba-2.2.7a/source/nsswitch/winbind_nss.c
samba-2.2.7a_sol/source/nsswitch/winbind_nss.c
*** samba-2.2.7a/source/nsswitch/winbind_nss.c  Wed Jul 17 06:47:50 2002
--- samba-2.2.7a_sol/source/nsswitch/winbind_nss.c      Fri Dec 13 14:12:02
2002
***************
*** 1332,1335 ****
--- 1332,1404 ----
        return ret;
  }
  
+ 
+ static NSS_STATUS fill_hostent(struct hostent *result,
+                              fstring winsresp,
+                              char **buffer, size_t *buflen)
+ {
+   unsigned long host_addr;
+   host_addr = inet_addr(winsresp);
+   if (host_addr == 0)
+     {
+       return NSS_STATUS_NOTFOUND;
+     }
+ 
+   bzero(result, sizeof(struct hostent));
+   result->h_name = strdup(winsresp);
+   result->h_aliases = (char**)malloc(sizeof(char*));
+   result->h_aliases[0] = NULL;
+   result->h_addrtype = AF_INET;
+   result->h_length = 4;  /* Handle ipv6 later */
+   result->h_addr_list = (char**) malloc(sizeof(char*) << 1);
+   result->h_addr_list[0] = (char*) malloc(sizeof host_addr);
+   result->h_addr_list[1] = NULL;
+   memcpy(result->h_addr_list[0], &host_addr, sizeof(host_addr));
+   return NSS_STATUS_SUCCESS;
+ }
+ 
+ /* Return passwd struct from username */
+ 
+ NSS_STATUS
+ _nss_winbind_gethostname_r(const char *name, struct hostent *result, 
+                       char *buffer,
+                       size_t buflen, int *errnop)
+ {
+       NSS_STATUS ret;
+       static struct winbindd_response response;
+       struct winbindd_request request;
+ 
+ #ifdef DEBUG_NSS
+       fprintf(stderr, "[%5d]: gethostname %s\n", getpid(), name);
+ #endif
+ 
+       /* Call for the first time */
+       
+       ZERO_STRUCT(response);
+       ZERO_STRUCT(request);
+       
+       strncpy(request.data.winsreq, name, 
+               sizeof(request.data.winsreq) - 1);
+       request.data.winsreq
+         [sizeof(request.data.winsreq) - 1] = '\0';
+       
+       ret = winbindd_request(WINBINDD_WINS_BYNAME, &request, &response);
+       
+       if (ret == NSS_STATUS_SUCCESS) {
+         ret = fill_hostent(result, response.data.winsresp, 
+                            &buffer,
+                            (int *)&buflen);
+         
+         if (ret == NSS_STATUS_TRYAGAIN) {
+           *errnop = errno = ERANGE;
+           return ret;
+         }
+       } 
+ 
+       free_response(&response);
+       return ret;
+ }
+ 
+ 
+ 
  #endif
diff -r -c samba-2.2.7a/source/nsswitch/winbind_nss_config.h
samba-2.2.7a_sol/source/nsswitch/winbind_nss_config.h
*** samba-2.2.7a/source/nsswitch/winbind_nss_config.h   Tue Dec 10 06:58:15
2002
--- samba-2.2.7a_sol/source/nsswitch/winbind_nss_config.h       Thu Dec 12
20:25:28 2002
***************
*** 91,96 ****
--- 91,100 ----
                                   struct group *result, char *buffer,
                                   size_t buflen, int *errnop);
  
+ NSS_STATUS _nss_winbind_gethostname_r(const char *name, 
+                                     struct hostent *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. */
  
diff -r -c samba-2.2.7a/source/nsswitch/winbind_nss_solaris.c
samba-2.2.7a_sol/source/nsswitch/winbind_nss_solaris.c
*** samba-2.2.7a/source/nsswitch/winbind_nss_solaris.c  Tue Apr 30 06:27:23
2002
--- samba-2.2.7a_sol/source/nsswitch/winbind_nss_solaris.c      Thu Dec 12
20:30:38 2002
***************
*** 278,283 ****
--- 278,349 ----
        return be;
  }
  
+ /*****************************************************************
+  HOSTS database backend
+  *****************************************************************/
+ 
+ 
+ static NSS_STATUS
+ _nss_winbind_gethostname_solwrap(nss_backend_t* be, void* args)
+ {
+       NSS_STATUS ret;
+       struct hostent* result = (struct hostent*)
NSS_ARGS(args)->buf.result;
+ 
+       NSS_DEBUG("_nss_winbind_gethostname_solwrap");
+       ret = _nss_winbind_gethostname_r(NSS_ARGS(args)->key.name,
+                                      result,
+                                      NSS_ARGS(args)->buf.buffer,
+                                      NSS_ARGS(args)->buf.buflen,
+                                      &NSS_ARGS(args)->erange);
+ 
+       if(ret == NSS_STATUS_SUCCESS)
+               NSS_ARGS(args)->returnval = (void*) result;
+   
+       return ret;
+ }
+   
+ static NSS_STATUS
+ _nss_winbind_gethostaddr_solwrap(nss_backend_t* be, void* args)
+ {
+       NSS_DEBUG("_nss_winbind_gethostaddr");
+       return NSS_STATUS_NOTFOUND;
+ }
+  
+ static NSS_STATUS
+ _nss_winbind_hosts_destr (nss_backend_t* be, void* args)
+ {
+       SAFE_FREE(be);
+       NSS_DEBUG("_nss_winbind_hosts_destr");
+       return NSS_STATUS_SUCCESS;
+ }
+ 
+ static nss_backend_op_t hosts_ops[] = 
+ {
+       _nss_winbind_hosts_destr,
+       NULL,
+       NULL,
+       NULL,
+       _nss_winbind_gethostname_solwrap,
+       _nss_winbind_gethostaddr_solwrap
+ }; 
+ 
+ nss_backend_t*
+ _nss_winbind_hosts_constr (const char* db_name,
+                          const char* src_name,
+                          const char* cfg_args)
+ {
+       nss_backend_t* be;
+ 
+       if(!(be = (nss_backend_t*) malloc(sizeof(nss_backend_t))) )
+               return NULL;
+ 
+       be->ops = hosts_ops;
+       be->n_ops = sizeof(hosts_ops) / sizeof(nss_backend_op_t);
+   
+       NSS_DEBUG("Initialized nss_winbind hosts backend");
+       return be;
+ }
+ 
  #endif /* SUN_NSS */
  
  
diff -r -c samba-2.2.7a/source/nsswitch/wins.c
samba-2.2.7a_sol/source/nsswitch/wins.c
*** samba-2.2.7a/source/nsswitch/wins.c Sun Jun  2 15:19:19 2002
--- samba-2.2.7a_sol/source/nsswitch/wins.c     Fri Dec 13 14:07:31 2002
***************
*** 334,339 ****
--- 334,402 ----
        return
_nss_wins_gethostbyname_r(name,he,buffer,buflen,errnop,h_errnop);
  }
  
+ #if SUNOS5
  
+ #define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
  
+ static NSS_STATUS
+ _nss_wins_gethostbyname_solwrap(nss_backend_t* be, void* args)
+ {
+       NSS_STATUS ret;
+       struct hostent* result = (struct hostent*)
NSS_ARGS(args)->buf.result;
+ 
+       ret = _nss_wins_gethostbyname_r (NSS_ARGS(args)->key.name,
+                                           result,
+                                           NSS_ARGS(args)->buf.buffer,
+                                           NSS_ARGS(args)->buf.buflen,
+                                           &NSS_ARGS(args)->erange,
+                                           NULL);
+ 
+       if(ret == NSS_STATUS_SUCCESS)
+               NSS_ARGS(args)->returnval = (void*) result;
+ 
+       return ret;
+ }
+ 
+ static NSS_STATUS
+ _nss_wins_gethostbyaddr_solwrap(nss_backend_t* be, void* args)
+ {
+       return NSS_STATUS_NOTFOUND;
+ }
+ 
+ static NSS_STATUS
+ _nss_wins_hosts_destr (nss_backend_t* be, void* args)
+ {
+       SAFE_FREE(be);
+       return NSS_STATUS_SUCCESS;
+ }
+ 
+ static nss_backend_op_t hosts_ops[] =
+ {
+       _nss_wins_hosts_destr,
+       NULL,
+       NULL,
+       NULL,
+       _nss_wins_gethostbyname_solwrap,
+       _nss_wins_gethostbyaddr_solwrap
+ };
+ 
+ nss_backend_t*
+ _nss_wins_hosts_constr (const char* db_name,
+                          const char* src_name,
+                          const char* cfg_args)
+ {
+       nss_backend_t* be;
+ 
+       if(!(be = (nss_backend_t*) malloc(sizeof(nss_backend_t))) )
+               return NULL;
+ 
+       be->ops = hosts_ops;
+       be->n_ops = sizeof(hosts_ops) / sizeof(nss_backend_op_t);
+ 
+       return be;
+ }
+ 
+ 
  #endif
+ 
+ #endif

Reply via email to