root/nsswitch/winbind_nss_solaris.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _nss_winbind_setpwent_solwrap
  2. _nss_winbind_endpwent_solwrap
  3. _nss_winbind_getpwent_solwrap
  4. _nss_winbind_getpwnam_solwrap
  5. _nss_winbind_getpwuid_solwrap
  6. _nss_winbind_passwd_destr
  7. _nss_winbind_passwd_constr
  8. _nss_winbind_setgrent_solwrap
  9. _nss_winbind_endgrent_solwrap
  10. _nss_winbind_getgrent_solwrap
  11. _nss_winbind_getgrnam_solwrap
  12. _nss_winbind_getgrgid_solwrap
  13. _nss_winbind_getgroupsbymember_solwrap
  14. _nss_winbind_group_destr
  15. _nss_winbind_group_constr
  16. parse_response
  17. _nss_winbind_ipnodes_getbyname
  18. _nss_winbind_hosts_getbyname
  19. _nss_winbind_hosts_getbyaddr
  20. _nss_winbind_common_endent
  21. _nss_winbind_common_setent
  22. _nss_winbind_common_getent
  23. _nss_winbind_common_constr
  24. _nss_winbind_common_destr
  25. _nss_winbind_ipnodes_constr
  26. _nss_winbind_hosts_constr

   1 /*
   2   Solaris NSS wrapper for winbind
   3   - Shirish Kalele 2000
   4 
   5   Based on Luke Howard's ldap_nss module for Solaris
   6   */
   7 
   8 /*
   9   Copyright (C) 1997-2003 Luke Howard.
  10   This file is part of the nss_ldap library.
  11 
  12   The nss_ldap library is free software; you can redistribute it and/or
  13   modify it under the terms of the GNU Lesser General Public License as
  14   published by the Free Software Foundation; either version 3 of the
  15   License, or (at your option) any later version.
  16 
  17   The nss_ldap library is distributed in the hope that it will be useful,
  18   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20   Library General Public License for more details.
  21 
  22   You should have received a copy of the GNU Lesser General Public
  23   License along with the nss_ldap library; see the file COPYING.LIB.  If not,
  24   see <http://www.gnu.org/licenses/>.
  25 */
  26 
  27 #undef DEVELOPER
  28 
  29 #include "winbind_client.h"
  30 #include <stdlib.h>
  31 #include <sys/types.h>
  32 #include <sys/param.h>
  33 #include <string.h>
  34 #include <pwd.h>
  35 #include "includes.h"
  36 #include <syslog.h>
  37 #if !defined(HPUX)
  38 #include <sys/syslog.h>
  39 #endif /*hpux*/
  40 
  41 #if defined(HAVE_NSS_COMMON_H) || defined(HPUX)
  42 
  43 #undef NSS_DEBUG
  44 
  45 #ifdef NSS_DEBUG
  46 #define NSS_DEBUG(str) syslog(LOG_DEBUG, "nss_winbind: %s", str);
  47 #else
  48 #define NSS_DEBUG(str) ;
  49 #endif
  50 
  51 #define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
  52 
  53 #ifdef HPUX
  54 
  55 /*
  56  * HP-UX 11 has no definiton of the nss_groupsbymem structure.   This
  57  * definition is taken from the nss_ldap project at:
  58  *  http://www.padl.com/OSS/nss_ldap.html
  59  */
  60 
  61 struct nss_groupsbymem {
  62        const char *username;
  63        gid_t *gid_array;
  64        int maxgids;
  65        int force_slow_way;
  66        int (*str2ent)(const char *instr, int instr_len, void *ent,
  67                       char *buffer, int buflen);
  68        nss_status_t (*process_cstr)(const char *instr, int instr_len,
  69                                     struct nss_groupsbymem *);
  70        int numgids;
  71 };
  72 
  73 #endif /* HPUX */
  74 
  75 #define make_pwent_str(dest, src)                                       \
  76 {                                                                       \
  77   if((dest = get_static(buffer, buflen, strlen(src)+1)) == NULL)        \
  78     {                                                                   \
  79       *errnop = ERANGE;                                                 \
  80       NSS_DEBUG("ERANGE error");                                        \
  81       return NSS_STATUS_TRYAGAIN;                                       \
  82     }                                                                   \
  83   strcpy(dest, src);                                                    \
  84 }
  85 
  86 static NSS_STATUS _nss_winbind_setpwent_solwrap (nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
  87 {
  88         NSS_DEBUG("_nss_winbind_setpwent_solwrap");
  89         return _nss_winbind_setpwent();
  90 }
  91 
  92 static NSS_STATUS
  93 _nss_winbind_endpwent_solwrap (nss_backend_t * be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
  94 {
  95         NSS_DEBUG("_nss_winbind_endpwent_solwrap");
  96         return _nss_winbind_endpwent();
  97 }
  98 
  99 static NSS_STATUS
 100 _nss_winbind_getpwent_solwrap (nss_backend_t* be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 101 {
 102         NSS_STATUS ret;
 103         char* buffer = NSS_ARGS(args)->buf.buffer;
 104         int buflen = NSS_ARGS(args)->buf.buflen;
 105         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
 106         int* errnop = &NSS_ARGS(args)->erange;
 107         char logmsg[80];
 108 
 109         ret = _nss_winbind_getpwent_r(result, buffer,
 110                                       buflen, errnop);
 111 
 112         if(ret == NSS_STATUS_SUCCESS)
 113                 {
 114                         snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning user: %s\n",
 115                                  result->pw_name);
 116                         NSS_DEBUG(logmsg);
 117                         NSS_ARGS(args)->returnval = (void*) result;
 118                 } else {
 119                         snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning error: %d.\n",ret);
 120                         NSS_DEBUG(logmsg);
 121                 }
 122 
 123         return ret;
 124 }
 125 
 126 static NSS_STATUS
 127 _nss_winbind_getpwnam_solwrap (nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 128 {
 129         NSS_STATUS ret;
 130         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
 131 
 132         NSS_DEBUG("_nss_winbind_getpwnam_solwrap");
 133 
 134         ret = _nss_winbind_getpwnam_r (NSS_ARGS(args)->key.name,
 135                                                 result,
 136                                                 NSS_ARGS(args)->buf.buffer,
 137                                                 NSS_ARGS(args)->buf.buflen,
 138                                                 &NSS_ARGS(args)->erange);
 139         if(ret == NSS_STATUS_SUCCESS)
 140                 NSS_ARGS(args)->returnval = (void*) result;
 141 
 142         return ret;
 143 }
 144 
 145 static NSS_STATUS
 146 _nss_winbind_getpwuid_solwrap(nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 147 {
 148         NSS_STATUS ret;
 149         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
 150 
 151         NSS_DEBUG("_nss_winbind_getpwuid_solwrap");
 152         ret = _nss_winbind_getpwuid_r (NSS_ARGS(args)->key.uid,
 153                                        result,
 154                                        NSS_ARGS(args)->buf.buffer,
 155                                        NSS_ARGS(args)->buf.buflen,
 156                                        &NSS_ARGS(args)->erange);
 157         if(ret == NSS_STATUS_SUCCESS)
 158                 NSS_ARGS(args)->returnval = (void*) result;
 159 
 160         return ret;
 161 }
 162 
 163 static NSS_STATUS _nss_winbind_passwd_destr (nss_backend_t * be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 164 {
 165         SAFE_FREE(be);
 166         NSS_DEBUG("_nss_winbind_passwd_destr");
 167         return NSS_STATUS_SUCCESS;
 168 }
 169 
 170 static nss_backend_op_t passwd_ops[] =
 171 {
 172         _nss_winbind_passwd_destr,
 173         _nss_winbind_endpwent_solwrap,          /* NSS_DBOP_ENDENT */
 174         _nss_winbind_setpwent_solwrap,          /* NSS_DBOP_SETENT */
 175         _nss_winbind_getpwent_solwrap,          /* NSS_DBOP_GETENT */
 176         _nss_winbind_getpwnam_solwrap,          /* NSS_DBOP_PASSWD_BYNAME */
 177         _nss_winbind_getpwuid_solwrap           /* NSS_DBOP_PASSWD_BYUID */
 178 };
 179 
 180 nss_backend_t*
 181 _nss_winbind_passwd_constr (const char* db_name,
     /* [<][>][^][v][top][bottom][index][help] */
 182                             const char* src_name,
 183                             const char* cfg_args)
 184 {
 185         nss_backend_t *be;
 186 
 187         if(!(be = SMB_MALLOC_P(nss_backend_t)) )
 188                 return NULL;
 189 
 190         be->ops = passwd_ops;
 191         be->n_ops = sizeof(passwd_ops) / sizeof(nss_backend_op_t);
 192 
 193         NSS_DEBUG("Initialized nss_winbind passwd backend");
 194         return be;
 195 }
 196 
 197 /*****************************************************************
 198  GROUP database backend
 199  *****************************************************************/
 200 
 201 static NSS_STATUS _nss_winbind_setgrent_solwrap (nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 202 {
 203         NSS_DEBUG("_nss_winbind_setgrent_solwrap");
 204         return _nss_winbind_setgrent();
 205 }
 206 
 207 static NSS_STATUS
 208 _nss_winbind_endgrent_solwrap (nss_backend_t * be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 209 {
 210         NSS_DEBUG("_nss_winbind_endgrent_solwrap");
 211         return _nss_winbind_endgrent();
 212 }
 213 
 214 static NSS_STATUS
 215 _nss_winbind_getgrent_solwrap(nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 216 {
 217         NSS_STATUS ret;
 218         char* buffer = NSS_ARGS(args)->buf.buffer;
 219         int buflen = NSS_ARGS(args)->buf.buflen;
 220         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
 221         int* errnop = &NSS_ARGS(args)->erange;
 222         char logmsg[80];
 223 
 224         ret = _nss_winbind_getgrent_r(result, buffer,
 225                                       buflen, errnop);
 226 
 227         if(ret == NSS_STATUS_SUCCESS)
 228                 {
 229                         snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning group: %s\n", result->gr_name);
 230                         NSS_DEBUG(logmsg);
 231                         NSS_ARGS(args)->returnval = (void*) result;
 232                 } else {
 233                         snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning error: %d.\n", ret);
 234                         NSS_DEBUG(logmsg);
 235                 }
 236 
 237         return ret;
 238 
 239 }
 240 
 241 static NSS_STATUS
 242 _nss_winbind_getgrnam_solwrap(nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 243 {
 244         NSS_STATUS ret;
 245         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
 246 
 247         NSS_DEBUG("_nss_winbind_getgrnam_solwrap");
 248         ret = _nss_winbind_getgrnam_r(NSS_ARGS(args)->key.name,
 249                                       result,
 250                                       NSS_ARGS(args)->buf.buffer,
 251                                       NSS_ARGS(args)->buf.buflen,
 252                                       &NSS_ARGS(args)->erange);
 253 
 254         if(ret == NSS_STATUS_SUCCESS)
 255                 NSS_ARGS(args)->returnval = (void*) result;
 256 
 257         return ret;
 258 }
 259 
 260 static NSS_STATUS
 261 _nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 262 {
 263         NSS_STATUS ret;
 264         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
 265 
 266         NSS_DEBUG("_nss_winbind_getgrgid_solwrap");
 267         ret = _nss_winbind_getgrgid_r (NSS_ARGS(args)->key.gid,
 268                                        result,
 269                                        NSS_ARGS(args)->buf.buffer,
 270                                        NSS_ARGS(args)->buf.buflen,
 271                                        &NSS_ARGS(args)->erange);
 272 
 273         if(ret == NSS_STATUS_SUCCESS)
 274                 NSS_ARGS(args)->returnval = (void*) result;
 275 
 276         return ret;
 277 }
 278 
 279 static NSS_STATUS
 280 _nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 281 {
 282         int errnop;
 283         struct nss_groupsbymem *gmem = (struct nss_groupsbymem *)args;
 284         long int numgids = gmem->numgids;
 285         long int maxgids = gmem->maxgids;
 286 
 287         NSS_DEBUG("_nss_winbind_getgroupsbymember");
 288 
 289         _nss_winbind_initgroups_dyn(gmem->username,
 290                 gmem->gid_array[0], /* Primary Group */
 291                 &numgids,
 292                 &maxgids,
 293                 &gmem->gid_array,
 294                 gmem->maxgids,
 295                 &errnop);
 296 
 297         gmem->numgids = numgids;
 298         gmem->maxgids = maxgids;
 299 
 300         /*
 301          * If the maximum number of gids have been found, return
 302          * SUCCESS so the switch engine will stop searching. Otherwise
 303          * return NOTFOUND so nsswitch will continue to get groups
 304          * from the remaining database backends specified in the
 305          * nsswitch.conf file.
 306          */
 307         return (gmem->numgids == gmem->maxgids ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND);
 308 }
 309 
 310 static NSS_STATUS
 311 _nss_winbind_group_destr (nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 312 {
 313         SAFE_FREE(be);
 314         NSS_DEBUG("_nss_winbind_group_destr");
 315         return NSS_STATUS_SUCCESS;
 316 }
 317 
 318 static nss_backend_op_t group_ops[] =
 319 {
 320         _nss_winbind_group_destr,
 321         _nss_winbind_endgrent_solwrap,
 322         _nss_winbind_setgrent_solwrap,
 323         _nss_winbind_getgrent_solwrap,
 324         _nss_winbind_getgrnam_solwrap,
 325         _nss_winbind_getgrgid_solwrap,
 326         _nss_winbind_getgroupsbymember_solwrap
 327 };
 328 
 329 nss_backend_t*
 330 _nss_winbind_group_constr (const char* db_name,
     /* [<][>][^][v][top][bottom][index][help] */
 331                            const char* src_name,
 332                            const char* cfg_args)
 333 {
 334         nss_backend_t* be;
 335 
 336         if(!(be = SMB_MALLOC_P(nss_backend_t)) )
 337                 return NULL;
 338 
 339         be->ops = group_ops;
 340         be->n_ops = sizeof(group_ops) / sizeof(nss_backend_op_t);
 341 
 342         NSS_DEBUG("Initialized nss_winbind group backend");
 343         return be;
 344 }
 345 
 346 /*****************************************************************
 347  hosts and ipnodes backend
 348  *****************************************************************/
 349 #if defined(SUNOS5)     /* not compatible with HP-UX */
 350 
 351 /* this parser is shared between get*byname and get*byaddr, as key type
 352    in request is stored in different locations, I had to provide the
 353    address family as an argument, caller must free the winbind response. */
 354 
 355 static NSS_STATUS
 356 parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response)
     /* [<][>][^][v][top][bottom][index][help] */
 357 {
 358         struct hostent *he = (struct hostent *)argp->buf.result;
 359         char *buffer = argp->buf.buffer;
 360         int buflen =  argp->buf.buflen;
 361         NSS_STATUS ret;
 362 
 363         char *p, *data;
 364         int addrcount = 0;
 365         int len = 0;
 366         struct in_addr *addrp;
 367 #if defined(AF_INET6)
 368         struct in6_addr *addrp6;
 369 #endif
 370         int i;
 371 
 372         /* response is tab separated list of ip addresses with hostname
 373            and newline at the end. so at first we will strip newline
 374            then construct list of addresses for hostent.
 375         */
 376         p = strchr(response->data.winsresp, '\n');
 377         if(p) *p = '\0';
 378         else {/* it must be broken */
 379                 argp->h_errno = NO_DATA;
 380                 return NSS_STATUS_UNAVAIL;
 381         }
 382 
 383         for(; p != response->data.winsresp; p--) {
 384                 if(*p == '\t') addrcount++;
 385         }
 386 
 387         if(addrcount == 0) {/* it must be broken */
 388                 argp->h_errno = NO_DATA;
 389                 return NSS_STATUS_UNAVAIL;
 390         }
 391 
 392         /* allocate space for addresses and h_addr_list */
 393         he->h_addrtype = af;
 394         if( he->h_addrtype == AF_INET) {
 395                 he->h_length =  sizeof(struct in_addr);
 396                 addrp = (struct in_addr *)ROUND_DOWN(buffer + buflen,
 397                                                 sizeof(struct in_addr));
 398                 addrp -= addrcount;
 399                 he->h_addr_list = (char **)ROUND_DOWN(addrp, sizeof (char*));
 400                 he->h_addr_list -= addrcount+1;
 401         }
 402 #if defined(AF_INET6)
 403         else {
 404                 he->h_length = sizeof(struct in6_addr);
 405                 addrp6 = (struct in6_addr *)ROUND_DOWN(buffer + buflen,
 406                                                 sizeof(struct in6_addr));
 407                 addrp6 -= addrcount;
 408                 he->h_addr_list = (char **)ROUND_DOWN(addrp6, sizeof (char*));
 409                 he->h_addr_list -= addrcount+1;
 410         }
 411 #endif
 412 
 413         /* buffer too small?! */
 414         if((char *)he->h_addr_list < buffer ) {
 415                 argp->erange = 1;
 416                 return NSS_STR_PARSE_ERANGE;
 417         }
 418 
 419         data = response->data.winsresp;
 420         for( i = 0; i < addrcount; i++) {
 421                 p = strchr(data, '\t');
 422                 if(p == NULL) break; /* just in case... */
 423 
 424                 *p = '\0'; /* terminate the string */
 425                 if(he->h_addrtype == AF_INET) {
 426                   he->h_addr_list[i] = (char *)&addrp[i];
 427                   if ((addrp[i].s_addr = inet_addr(data)) == -1) {
 428                     argp->erange = 1;
 429                     return NSS_STR_PARSE_ERANGE;
 430                   }
 431                 }
 432 #if defined(AF_INET6)
 433                 else {
 434                   he->h_addr_list[i] = (char *)&addrp6[i];
 435                   if (strchr(data, ':') != 0) {
 436                         if (inet_pton(AF_INET6, data, &addrp6[i]) != 1) {
 437                           argp->erange = 1;
 438                           return NSS_STR_PARSE_ERANGE;
 439                         }
 440                   } else {
 441                         struct in_addr in4;
 442                         if ((in4.s_addr = inet_addr(data)) == -1) {
 443                           argp->erange = 1;
 444                           return NSS_STR_PARSE_ERANGE;
 445                         }
 446                         IN6_INADDR_TO_V4MAPPED(&in4, &addrp6[i]);
 447                   }
 448                 }
 449 #endif
 450                 data = p+1;
 451         }
 452 
 453         he->h_addr_list[i] = (char *)NULL;
 454 
 455         len = strlen(data);
 456         if(len > he->h_addr_list - (char**)argp->buf.buffer) {
 457                 argp->erange = 1;
 458                 return NSS_STR_PARSE_ERANGE;
 459         }
 460 
 461         /* this is a bit overkill to use _nss_netdb_aliases here since
 462            there seems to be no aliases but it will create all data for us */
 463         he->h_aliases = _nss_netdb_aliases(data, len, buffer,
 464                                 ((char*) he->h_addr_list) - buffer);
 465         if(he->h_aliases == NULL) {
 466             argp->erange = 1;
 467             ret = NSS_STR_PARSE_ERANGE;
 468         } else {
 469             he->h_name = he->h_aliases[0];
 470             he->h_aliases++;
 471             ret = NSS_STR_PARSE_SUCCESS;
 472         }
 473 
 474         argp->returnval = (void*)he;
 475         return ret;
 476 }
 477 
 478 static NSS_STATUS
 479 _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 480 {
 481         nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
 482         struct winbindd_response response;
 483         struct winbindd_request request;
 484         NSS_STATUS ret;
 485         int af;
 486 
 487         ZERO_STRUCT(response);
 488         ZERO_STRUCT(request);
 489 
 490         /* I assume there that AI_ADDRCONFIG cases are handled in nss
 491            frontend code, at least it seems done so in solaris...
 492 
 493            we will give NO_DATA for pure IPv6; IPv4 will be returned for
 494            AF_INET or for AF_INET6 and AI_ALL|AI_V4MAPPED we have to map
 495            IPv4 to IPv6.
 496          */
 497 #if defined(AF_INET6)
 498 #ifdef HAVE_NSS_XBYY_KEY_IPNODE
 499         af = argp->key.ipnode.af_family;
 500         if(af == AF_INET6 && argp->key.ipnode.flags == 0) {
 501                 argp->h_errno = NO_DATA;
 502                 return NSS_STATUS_UNAVAIL;
 503         }
 504 #else
 505         /* I'm not that sure if this is correct, but... */
 506         af = AF_INET6;
 507 #endif
 508 #endif
 509 
 510         strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
 511         request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
 512 
 513         if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
 514                 == NSS_STATUS_SUCCESS ) {
 515           ret = parse_response(af, argp, &response);
 516         }
 517 
 518         winbindd_free_response(&response);
 519         return ret;
 520 }
 521 
 522 static NSS_STATUS
 523 _nss_winbind_hosts_getbyname(nss_backend_t* be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 524 {
 525         nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
 526         struct winbindd_response response;
 527         struct winbindd_request request;
 528         NSS_STATUS ret;
 529 
 530         ZERO_STRUCT(response);
 531         ZERO_STRUCT(request);
 532 
 533         strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
 534         request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
 535 
 536         if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
 537                 == NSS_STATUS_SUCCESS ) {
 538           ret = parse_response(AF_INET, argp, &response);
 539         }
 540 
 541         winbindd_free_response(&response);
 542         return ret;
 543 }
 544 
 545 static NSS_STATUS
 546 _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 547 {
 548         NSS_STATUS ret;
 549         struct winbindd_response response;
 550         struct winbindd_request request;
 551         nss_XbyY_args_t *argp = (nss_XbyY_args_t *)args;
 552         const char *p;
 553 
 554         ZERO_STRUCT(response);
 555         ZERO_STRUCT(request);
 556 
 557 #if defined(AF_INET6)
 558         /* winbindd currently does not resolve IPv6 */
 559         if(argp->key.hostaddr.type == AF_INET6) {
 560                 argp->h_errno = NO_DATA;
 561                 return NSS_STATUS_UNAVAIL;
 562         }
 563 
 564         p = inet_ntop(argp->key.hostaddr.type, argp->key.hostaddr.addr,
 565                         request.data.winsreq, sizeof request.data.winsreq);
 566 #else
 567         snprintf(request.data.winsreq, sizeof request.data.winsreq,
 568                 "%u.%u.%u.%u",
 569                 ((unsigned char *)argp->key.hostaddr.addr)[0],
 570                 ((unsigned char *)argp->key.hostaddr.addr)[1],
 571                 ((unsigned char *)argp->key.hostaddr.addr)[2],
 572                 ((unsigned char *)argp->key.hostaddr.addr)[3]);
 573 #endif
 574 
 575         ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response);
 576 
 577         if( ret == NSS_STATUS_SUCCESS) {
 578           parse_response(argp->key.hostaddr.type, argp, &response);
 579         }
 580         winbindd_free_response(&response);
 581         return ret;
 582 }
 583 
 584 /* winbind does not provide setent, getent, endent for wins */
 585 static NSS_STATUS
 586 _nss_winbind_common_endent(nss_backend_t* be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 587 {
 588         return (NSS_STATUS_UNAVAIL);
 589 }
 590 
 591 static NSS_STATUS
 592 _nss_winbind_common_setent(nss_backend_t* be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 593 {
 594         return (NSS_STATUS_UNAVAIL);
 595 }
 596 
 597 static NSS_STATUS
 598 _nss_winbind_common_getent(nss_backend_t* be, void *args)
     /* [<][>][^][v][top][bottom][index][help] */
 599 {
 600         return (NSS_STATUS_UNAVAIL);
 601 }
 602 
 603 static nss_backend_t*
 604 _nss_winbind_common_constr (nss_backend_op_t ops[], int n_ops)
     /* [<][>][^][v][top][bottom][index][help] */
 605 {
 606         nss_backend_t* be;
 607 
 608         if(!(be = SMB_MALLOC_P(nss_backend_t)) )
 609         return NULL;
 610 
 611         be->ops = ops;
 612         be->n_ops = n_ops;
 613 
 614         return be;
 615 }
 616 
 617 static NSS_STATUS
 618 _nss_winbind_common_destr (nss_backend_t* be, void* args)
     /* [<][>][^][v][top][bottom][index][help] */
 619 {
 620         SAFE_FREE(be);
 621         return NSS_STATUS_SUCCESS;
 622 }
 623 
 624 static nss_backend_op_t ipnodes_ops[] = {
 625         _nss_winbind_common_destr,
 626         _nss_winbind_common_endent,
 627         _nss_winbind_common_setent,
 628         _nss_winbind_common_getent,
 629         _nss_winbind_ipnodes_getbyname,
 630         _nss_winbind_hosts_getbyaddr,
 631 };
 632 
 633 nss_backend_t *
 634 _nss_winbind_ipnodes_constr(dummy1, dummy2, dummy3)
     /* [<][>][^][v][top][bottom][index][help] */
 635         const char      *dummy1, *dummy2, *dummy3;
 636 {
 637         return (_nss_winbind_common_constr(ipnodes_ops,
 638                 sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0])));
 639 }
 640 
 641 static nss_backend_op_t host_ops[] = {
 642         _nss_winbind_common_destr,
 643         _nss_winbind_common_endent,
 644         _nss_winbind_common_setent,
 645         _nss_winbind_common_getent,
 646         _nss_winbind_hosts_getbyname,
 647         _nss_winbind_hosts_getbyaddr,
 648 };
 649 
 650 nss_backend_t *
 651 _nss_winbind_hosts_constr(dummy1, dummy2, dummy3)
     /* [<][>][^][v][top][bottom][index][help] */
 652         const char      *dummy1, *dummy2, *dummy3;
 653 {
 654         return (_nss_winbind_common_constr(host_ops,
 655                 sizeof (host_ops) / sizeof (host_ops[0])));
 656 }
 657 
 658 #endif  /* defined(SUNOS5) */
 659 #endif  /* defined(HAVE_NSS_COMMON_H) || defined(HPUX) */

/* [<][>][^][v][top][bottom][index][help] */