nsswitch/winbind_nss_solaris.c

説明を見る。
00001 /*
00002   Solaris NSS wrapper for winbind 
00003   - Shirish Kalele 2000
00004   
00005   Based on Luke Howard's ldap_nss module for Solaris 
00006   */
00007 
00008 /*
00009   Copyright (C) 1997-2003 Luke Howard.
00010   This file is part of the nss_ldap library.
00011 
00012   The nss_ldap library is free software; you can redistribute it and/or
00013   modify it under the terms of the GNU Library General Public License as
00014   published by the Free Software Foundation; either version 2 of the
00015   License, or (at your option) any later version.
00016 
00017   The nss_ldap library is distributed in the hope that it will be useful,
00018   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020   Library General Public License for more details.
00021 
00022   You should have received a copy of the GNU Library General Public
00023   License along with the nss_ldap library; see the file COPYING.LIB.  If not,
00024   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00025   Boston, MA 02111-1307, USA.
00026 */
00027 
00028 #undef DEVELOPER
00029 
00030 #include <stdlib.h>
00031 #include <sys/types.h>
00032 #include <sys/param.h>
00033 #include <string.h>
00034 #include <pwd.h>
00035 #include "includes.h"
00036 #include <syslog.h>
00037 #if !defined(HPUX)
00038 #include <sys/syslog.h>
00039 #endif /*hpux*/
00040 #include "winbind_nss_config.h"
00041 
00042 #if defined(HAVE_NSS_COMMON_H) || defined(HPUX) 
00043 
00044 #undef NSS_DEBUG
00045 
00046 #ifdef NSS_DEBUG
00047 #define NSS_DEBUG(str) syslog(LOG_DEBUG, "nss_winbind: %s", str);
00048 #else
00049 #define NSS_DEBUG(str) ;
00050 #endif
00051 
00052 #define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
00053 
00054 #ifdef HPUX
00055 
00056 /*
00057  * HP-UX 11 has no definiton of the nss_groupsbymem structure.   This
00058  * definition is taken from the nss_ldap project at:
00059  *  http://www.padl.com/OSS/nss_ldap.html
00060  */
00061 
00062 struct nss_groupsbymem {
00063        const char *username;
00064        gid_t *gid_array;
00065        int maxgids;
00066        int force_slow_way;
00067        int (*str2ent)(const char *instr, int instr_len, void *ent, 
00068                       char *buffer, int buflen);
00069        nss_status_t (*process_cstr)(const char *instr, int instr_len, 
00070                                     struct nss_groupsbymem *);
00071        int numgids;
00072 };
00073 
00074 #endif /* HPUX */
00075 
00076 #define make_pwent_str(dest, src)                                       \
00077 {                                                                       \
00078   if((dest = get_static(buffer, buflen, strlen(src)+1)) == NULL)        \
00079     {                                                                   \
00080       *errnop = ERANGE;                                                 \
00081       NSS_DEBUG("ERANGE error");                                        \
00082       return NSS_STATUS_TRYAGAIN;                                       \
00083     }                                                                   \
00084   strcpy(dest, src);                                                    \
00085 }
00086 
00087 static NSS_STATUS _nss_winbind_setpwent_solwrap (nss_backend_t* be, void* args)
00088 {
00089         NSS_DEBUG("_nss_winbind_setpwent_solwrap");
00090         return _nss_winbind_setpwent();
00091 }
00092 
00093 static NSS_STATUS
00094 _nss_winbind_endpwent_solwrap (nss_backend_t * be, void *args)
00095 {
00096         NSS_DEBUG("_nss_winbind_endpwent_solwrap");
00097         return _nss_winbind_endpwent();
00098 }
00099 
00100 static NSS_STATUS
00101 _nss_winbind_getpwent_solwrap (nss_backend_t* be, void *args)
00102 {
00103         NSS_STATUS ret;
00104         char* buffer = NSS_ARGS(args)->buf.buffer;
00105         int buflen = NSS_ARGS(args)->buf.buflen;
00106         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
00107         int* errnop = &NSS_ARGS(args)->erange;
00108         char logmsg[80];
00109 
00110         ret = _nss_winbind_getpwent_r(result, buffer, 
00111                                       buflen, errnop);
00112 
00113         if(ret == NSS_STATUS_SUCCESS)
00114                 {
00115                         snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning user: %s\n",
00116                                  result->pw_name);
00117                         NSS_DEBUG(logmsg);
00118                         NSS_ARGS(args)->returnval = (void*) result;
00119                 } else {
00120                         snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning error: %d.\n",ret);
00121                         NSS_DEBUG(logmsg);
00122                 }
00123     
00124         return ret;
00125 }
00126 
00127 static NSS_STATUS
00128 _nss_winbind_getpwnam_solwrap (nss_backend_t* be, void* args)
00129 {
00130         NSS_STATUS ret;
00131         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
00132 
00133         NSS_DEBUG("_nss_winbind_getpwnam_solwrap");
00134 
00135         ret = _nss_winbind_getpwnam_r (NSS_ARGS(args)->key.name,
00136                                                 result,
00137                                                 NSS_ARGS(args)->buf.buffer,
00138                                                 NSS_ARGS(args)->buf.buflen,
00139                                                 &NSS_ARGS(args)->erange);
00140         if(ret == NSS_STATUS_SUCCESS)
00141                 NSS_ARGS(args)->returnval = (void*) result;
00142   
00143         return ret;
00144 }
00145 
00146 static NSS_STATUS
00147 _nss_winbind_getpwuid_solwrap(nss_backend_t* be, void* args)
00148 {
00149         NSS_STATUS ret;
00150         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
00151   
00152         NSS_DEBUG("_nss_winbind_getpwuid_solwrap");
00153         ret = _nss_winbind_getpwuid_r (NSS_ARGS(args)->key.uid,
00154                                        result,
00155                                        NSS_ARGS(args)->buf.buffer,
00156                                        NSS_ARGS(args)->buf.buflen,
00157                                        &NSS_ARGS(args)->erange);
00158         if(ret == NSS_STATUS_SUCCESS)
00159                 NSS_ARGS(args)->returnval = (void*) result;
00160   
00161         return ret;
00162 }
00163 
00164 static NSS_STATUS _nss_winbind_passwd_destr (nss_backend_t * be, void *args)
00165 {
00166         SAFE_FREE(be);
00167         NSS_DEBUG("_nss_winbind_passwd_destr");
00168         return NSS_STATUS_SUCCESS;
00169 }
00170 
00171 static nss_backend_op_t passwd_ops[] =
00172 {
00173         _nss_winbind_passwd_destr,
00174         _nss_winbind_endpwent_solwrap,          /* NSS_DBOP_ENDENT */
00175         _nss_winbind_setpwent_solwrap,          /* NSS_DBOP_SETENT */
00176         _nss_winbind_getpwent_solwrap,          /* NSS_DBOP_GETENT */
00177         _nss_winbind_getpwnam_solwrap,          /* NSS_DBOP_PASSWD_BYNAME */
00178         _nss_winbind_getpwuid_solwrap           /* NSS_DBOP_PASSWD_BYUID */
00179 };
00180 
00181 nss_backend_t*
00182 _nss_winbind_passwd_constr (const char* db_name,
00183                             const char* src_name,
00184                             const char* cfg_args)
00185 {
00186         nss_backend_t *be;
00187   
00188         if(!(be = SMB_MALLOC_P(nss_backend_t)) )
00189                 return NULL;
00190 
00191         be->ops = passwd_ops;
00192         be->n_ops = sizeof(passwd_ops) / sizeof(nss_backend_op_t);
00193 
00194         NSS_DEBUG("Initialized nss_winbind passwd backend");
00195         return be;
00196 }
00197 
00198 /*****************************************************************
00199  GROUP database backend
00200  *****************************************************************/
00201 
00202 static NSS_STATUS _nss_winbind_setgrent_solwrap (nss_backend_t* be, void* args)
00203 {
00204         NSS_DEBUG("_nss_winbind_setgrent_solwrap");
00205         return _nss_winbind_setgrent();
00206 }
00207 
00208 static NSS_STATUS
00209 _nss_winbind_endgrent_solwrap (nss_backend_t * be, void *args)
00210 {
00211         NSS_DEBUG("_nss_winbind_endgrent_solwrap");
00212         return _nss_winbind_endgrent();
00213 }
00214 
00215 static NSS_STATUS
00216 _nss_winbind_getgrent_solwrap(nss_backend_t* be, void* args)
00217 {
00218         NSS_STATUS ret;
00219         char* buffer = NSS_ARGS(args)->buf.buffer;
00220         int buflen = NSS_ARGS(args)->buf.buflen;
00221         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
00222         int* errnop = &NSS_ARGS(args)->erange;
00223         char logmsg[80];
00224 
00225         ret = _nss_winbind_getgrent_r(result, buffer, 
00226                                       buflen, errnop);
00227 
00228         if(ret == NSS_STATUS_SUCCESS)
00229                 {
00230                         snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning group: %s\n", result->gr_name);
00231                         NSS_DEBUG(logmsg);
00232                         NSS_ARGS(args)->returnval = (void*) result;
00233                 } else {
00234                         snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning error: %d.\n", ret);
00235                         NSS_DEBUG(logmsg);
00236                 }
00237 
00238         return ret;
00239         
00240 }
00241 
00242 static NSS_STATUS
00243 _nss_winbind_getgrnam_solwrap(nss_backend_t* be, void* args)
00244 {
00245         NSS_STATUS ret;
00246         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
00247 
00248         NSS_DEBUG("_nss_winbind_getgrnam_solwrap");
00249         ret = _nss_winbind_getgrnam_r(NSS_ARGS(args)->key.name,
00250                                       result,
00251                                       NSS_ARGS(args)->buf.buffer,
00252                                       NSS_ARGS(args)->buf.buflen,
00253                                       &NSS_ARGS(args)->erange);
00254 
00255         if(ret == NSS_STATUS_SUCCESS)
00256                 NSS_ARGS(args)->returnval = (void*) result;
00257   
00258         return ret;
00259 }
00260   
00261 static NSS_STATUS
00262 _nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args)
00263 {
00264         NSS_STATUS ret;
00265         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
00266 
00267         NSS_DEBUG("_nss_winbind_getgrgid_solwrap");
00268         ret = _nss_winbind_getgrgid_r (NSS_ARGS(args)->key.gid,
00269                                        result,
00270                                        NSS_ARGS(args)->buf.buffer,
00271                                        NSS_ARGS(args)->buf.buflen,
00272                                        &NSS_ARGS(args)->erange);
00273 
00274         if(ret == NSS_STATUS_SUCCESS)
00275                 NSS_ARGS(args)->returnval = (void*) result;
00276 
00277         return ret;
00278 }
00279 
00280 static NSS_STATUS
00281 _nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
00282 {
00283         int errnop;
00284         struct nss_groupsbymem *gmem = (struct nss_groupsbymem *)args;
00285 
00286         NSS_DEBUG("_nss_winbind_getgroupsbymember");
00287 
00288         _nss_winbind_initgroups_dyn(gmem->username,
00289                 gmem->gid_array[0], /* Primary Group */
00290                 &gmem->numgids,
00291                 &gmem->maxgids,
00292                 &gmem->gid_array,
00293                 gmem->maxgids,
00294                 &errnop);
00295 
00296         /*
00297          * If the maximum number of gids have been found, return
00298          * SUCCESS so the switch engine will stop searching. Otherwise
00299          * return NOTFOUND so nsswitch will continue to get groups
00300          * from the remaining database backends specified in the
00301          * nsswitch.conf file.
00302          */
00303         return (gmem->numgids == gmem->maxgids ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND);
00304 }
00305 
00306 static NSS_STATUS
00307 _nss_winbind_group_destr (nss_backend_t* be, void* args)
00308 {
00309         SAFE_FREE(be);
00310         NSS_DEBUG("_nss_winbind_group_destr");
00311         return NSS_STATUS_SUCCESS;
00312 }
00313 
00314 static nss_backend_op_t group_ops[] = 
00315 {
00316         _nss_winbind_group_destr,
00317         _nss_winbind_endgrent_solwrap,
00318         _nss_winbind_setgrent_solwrap,
00319         _nss_winbind_getgrent_solwrap,
00320         _nss_winbind_getgrnam_solwrap,
00321         _nss_winbind_getgrgid_solwrap,
00322         _nss_winbind_getgroupsbymember_solwrap
00323 }; 
00324 
00325 nss_backend_t*
00326 _nss_winbind_group_constr (const char* db_name,
00327                            const char* src_name,
00328                            const char* cfg_args)
00329 {
00330         nss_backend_t* be;
00331 
00332         if(!(be = SMB_MALLOC_P(nss_backend_t)) )
00333                 return NULL;
00334 
00335         be->ops = group_ops;
00336         be->n_ops = sizeof(group_ops) / sizeof(nss_backend_op_t);
00337   
00338         NSS_DEBUG("Initialized nss_winbind group backend");
00339         return be;
00340 }
00341 
00342 /*****************************************************************
00343  hosts and ipnodes backend
00344  *****************************************************************/
00345 #if defined(SUNOS5)     /* not compatible with HP-UX */
00346 
00347 /* this parser is shared between get*byname and get*byaddr, as key type
00348    in request is stored in different locations, I had to provide the
00349    address family as an argument, caller must free the winbind response. */
00350 
00351 static NSS_STATUS
00352 parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response)
00353 {
00354         struct hostent *he = (struct hostent *)argp->buf.result;
00355         char *buffer = argp->buf.buffer;
00356         int buflen =  argp->buf.buflen;
00357         NSS_STATUS ret;
00358 
00359         char *p, *data;
00360         int addrcount = 0;
00361         int len = 0;
00362         struct in_addr *addrp;
00363         struct in6_addr *addrp6;
00364         int i;
00365 
00366         /* response is tab separated list of ip addresses with hostname
00367            and newline at the end. so at first we will strip newline
00368            then construct list of addresses for hostent.
00369         */
00370         p = strchr(response->data.winsresp, '\n');
00371         if(p) *p = '\0';
00372         else {/* it must be broken */
00373                 argp->h_errno = NO_DATA;
00374                 return NSS_STATUS_UNAVAIL;
00375         }
00376 
00377         for(; p != response->data.winsresp; p--) {
00378                 if(*p == '\t') addrcount++;
00379         }
00380 
00381         if(addrcount == 0) {/* it must be broken */
00382                 argp->h_errno = NO_DATA;
00383                 return NSS_STATUS_UNAVAIL;
00384         }
00385 
00386         /* allocate space for addresses and h_addr_list */
00387         he->h_addrtype = af;
00388         if( he->h_addrtype == AF_INET) {
00389                 he->h_length =  sizeof(struct in_addr);
00390                 addrp = (struct in_addr *)ROUND_DOWN(buffer + buflen,
00391                                                 sizeof(struct in_addr));
00392                 addrp -= addrcount;
00393                 he->h_addr_list = (char **)ROUND_DOWN(addrp, sizeof (char*));
00394                 he->h_addr_list -= addrcount+1;
00395         } else {
00396                 he->h_length = sizeof(struct in6_addr);
00397                 addrp6 = (struct in6_addr *)ROUND_DOWN(buffer + buflen,
00398                                                 sizeof(struct in6_addr));
00399                 addrp6 -= addrcount;
00400                 he->h_addr_list = (char **)ROUND_DOWN(addrp6, sizeof (char*));
00401                 he->h_addr_list -= addrcount+1;
00402         }
00403 
00404         /* buffer too small?! */
00405         if((char *)he->h_addr_list < buffer ) {
00406                 argp->erange = 1;
00407                 return NSS_STR_PARSE_ERANGE;
00408         }
00409         
00410         data = response->data.winsresp;
00411         for( i = 0; i < addrcount; i++) {
00412                 p = strchr(data, '\t');
00413                 if(p == NULL) break; /* just in case... */
00414 
00415                 *p = '\0'; /* terminate the string */
00416                 if(he->h_addrtype == AF_INET) {
00417                   he->h_addr_list[i] = (char *)&addrp[i];
00418                   if ((addrp[i].s_addr = inet_addr(data)) == -1) {
00419                     argp->erange = 1;
00420                     return NSS_STR_PARSE_ERANGE;
00421                   }
00422                 } else {
00423                   he->h_addr_list[i] = (char *)&addrp6[i];
00424                   if (strchr(data, ':') != 0) {
00425                         if (inet_pton(AF_INET6, data, &addrp6[i]) != 1) {
00426                           argp->erange = 1;
00427                           return NSS_STR_PARSE_ERANGE;
00428                         }
00429                   } else {
00430                         struct in_addr in4;
00431                         if ((in4.s_addr = inet_addr(data)) == -1) {
00432                           argp->erange = 1;
00433                           return NSS_STR_PARSE_ERANGE;
00434                         }
00435                         IN6_INADDR_TO_V4MAPPED(&in4, &addrp6[i]);
00436                   }
00437                 }
00438                 data = p+1;
00439         }
00440 
00441         he->h_addr_list[i] = (char *)NULL;
00442 
00443         len = strlen(data);
00444         if(len > he->h_addr_list - (char**)argp->buf.buffer) {
00445                 argp->erange = 1;
00446                 return NSS_STR_PARSE_ERANGE;
00447         }
00448 
00449         /* this is a bit overkill to use _nss_netdb_aliases here since
00450            there seems to be no aliases but it will create all data for us */
00451         he->h_aliases = _nss_netdb_aliases(data, len, buffer,
00452                                 ((char*) he->h_addr_list) - buffer);
00453         if(he->h_aliases == NULL) {
00454             argp->erange = 1;
00455             ret = NSS_STR_PARSE_ERANGE;
00456         } else {
00457             he->h_name = he->h_aliases[0];
00458             he->h_aliases++;
00459             ret = NSS_STR_PARSE_SUCCESS;
00460         }
00461 
00462         argp->returnval = (void*)he;
00463         return ret;
00464 }
00465 
00466 static NSS_STATUS
00467 _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args)
00468 {
00469         nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
00470         struct winbindd_response response;
00471         struct winbindd_request request;
00472         NSS_STATUS ret;
00473         int af;
00474 
00475         ZERO_STRUCT(response);
00476         ZERO_STRUCT(request);
00477 
00478         /* I assume there that AI_ADDRCONFIG cases are handled in nss
00479            frontend code, at least it seems done so in solaris...
00480 
00481            we will give NO_DATA for pure IPv6; IPv4 will be returned for
00482            AF_INET or for AF_INET6 and AI_ALL|AI_V4MAPPED we have to map
00483            IPv4 to IPv6.
00484          */
00485 #ifdef HAVE_NSS_XBYY_KEY_IPNODE
00486         af = argp->key.ipnode.af_family;
00487         if(af == AF_INET6 && argp->key.ipnode.flags == 0) {
00488                 argp->h_errno = NO_DATA;
00489                 return NSS_STATUS_UNAVAIL;
00490         }
00491 #else
00492         /* I'm not that sure if this is correct, but... */
00493         af = AF_INET6;
00494 #endif
00495 
00496         strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
00497         request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
00498 
00499         if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
00500                 == NSS_STATUS_SUCCESS ) {
00501           ret = parse_response(af, argp, &response);
00502         }
00503 
00504         free_response(&response);
00505         return ret;
00506 }
00507 
00508 static NSS_STATUS
00509 _nss_winbind_hosts_getbyname(nss_backend_t* be, void *args)
00510 {
00511         nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
00512         struct winbindd_response response;
00513         struct winbindd_request request;
00514         NSS_STATUS ret;
00515 
00516         ZERO_STRUCT(response);
00517         ZERO_STRUCT(request);
00518         
00519         strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
00520         request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
00521 
00522         if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
00523                 == NSS_STATUS_SUCCESS ) {
00524           ret = parse_response(AF_INET, argp, &response);
00525         }
00526 
00527         free_response(&response);
00528         return ret;
00529 }
00530 
00531 static NSS_STATUS
00532 _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args)
00533 {
00534         NSS_STATUS ret;
00535         struct winbindd_response response;
00536         struct winbindd_request request;
00537         nss_XbyY_args_t *argp = (nss_XbyY_args_t *)args;
00538         const char *p;
00539 
00540         ZERO_STRUCT(response);
00541         ZERO_STRUCT(request);
00542 
00543         /* winbindd currently does not resolve IPv6 */
00544         if(argp->key.hostaddr.type == AF_INET6) {
00545                 argp->h_errno = NO_DATA;
00546                 return NSS_STATUS_UNAVAIL;
00547         }
00548 
00549         p = inet_ntop(argp->key.hostaddr.type, argp->key.hostaddr.addr,
00550                         request.data.winsreq, INET6_ADDRSTRLEN);
00551 
00552         ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response);
00553 
00554         if( ret == NSS_STATUS_SUCCESS) {
00555           parse_response(argp->key.hostaddr.type, argp, &response);
00556         }
00557         free_response(&response);
00558         return ret;
00559 }
00560 
00561 /* winbind does not provide setent, getent, endent for wins */
00562 static NSS_STATUS
00563 _nss_winbind_common_endent(nss_backend_t* be, void *args)
00564 {
00565         return (NSS_STATUS_UNAVAIL);
00566 }
00567 
00568 static NSS_STATUS
00569 _nss_winbind_common_setent(nss_backend_t* be, void *args)
00570 {
00571         return (NSS_STATUS_UNAVAIL);
00572 }
00573 
00574 static NSS_STATUS
00575 _nss_winbind_common_getent(nss_backend_t* be, void *args)
00576 {
00577         return (NSS_STATUS_UNAVAIL);
00578 }
00579 
00580 static nss_backend_t*
00581 _nss_winbind_common_constr (nss_backend_op_t ops[], int n_ops)
00582 {
00583         nss_backend_t* be;
00584 
00585         if(!(be = SMB_MALLOC_P(nss_backend_t)) )
00586         return NULL;
00587 
00588         be->ops = ops;
00589         be->n_ops = n_ops;
00590 
00591         return be;
00592 }
00593 
00594 static NSS_STATUS
00595 _nss_winbind_common_destr (nss_backend_t* be, void* args)
00596 {
00597         SAFE_FREE(be);
00598         return NSS_STATUS_SUCCESS;
00599 }
00600 
00601 static nss_backend_op_t ipnodes_ops[] = {
00602         _nss_winbind_common_destr,
00603         _nss_winbind_common_endent,
00604         _nss_winbind_common_setent,
00605         _nss_winbind_common_getent,
00606         _nss_winbind_ipnodes_getbyname,
00607         _nss_winbind_hosts_getbyaddr,
00608 };
00609 
00610 nss_backend_t *
00611 _nss_winbind_ipnodes_constr(dummy1, dummy2, dummy3)
00612         const char      *dummy1, *dummy2, *dummy3;
00613 {
00614         return (_nss_winbind_common_constr(ipnodes_ops,
00615                 sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0])));
00616 }
00617 
00618 static nss_backend_op_t host_ops[] = {
00619         _nss_winbind_common_destr,
00620         _nss_winbind_common_endent,
00621         _nss_winbind_common_setent,
00622         _nss_winbind_common_getent,
00623         _nss_winbind_hosts_getbyname,
00624         _nss_winbind_hosts_getbyaddr,
00625 };
00626 
00627 nss_backend_t *
00628 _nss_winbind_hosts_constr(dummy1, dummy2, dummy3)
00629         const char      *dummy1, *dummy2, *dummy3;
00630 {
00631         return (_nss_winbind_common_constr(host_ops,
00632                 sizeof (host_ops) / sizeof (host_ops[0])));
00633 }
00634 
00635 #endif  /* defined(SUNOS5) */
00636 #endif  /* defined(HAVE_NSS_COMMON_H) || defined(HPUX) */

Sambaに対してSat Aug 29 21:23:09 2009に生成されました。  doxygen 1.4.7