/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* Common code and structures used by name-service-switch "nis" backends.
*/
#include "nis_common.h"
#include <string.h>
#include <synch.h>
#include <thread.h>
#include <ctype.h>
#include <stdlib.h>
#include <signal.h>
#ifndef MT_UNSAFE_YP /* Is the libnsl YP client code MT-unsafe? */
#endif
#if MT_UNSAFE_YP
#endif
typedef char *grrr;
/*
* The YP client code thinks it's being helpful by appending '\n' and '\0'
* to the values returned by yp_match() et al. In order to do this it
* ends up doing more malloc()ing and data copying than would otherwise
* be necessary. If we're interested in performance we should provide
* alternative library interfaces that skip the helpfulness and instead
* let the XDR routines dump the value directly into the buffer where
* we really want it. For now, though, we just use the vanilla interface.
*/
static nss_status_t
int ypstatus;
int ismatch;
{
switch (ypstatus) {
case 0:
errno = 0;
return (NSS_SUCCESS);
case YPERR_BADARGS:
case YPERR_KEY:
errno = 0;
return (NSS_NOTFOUND);
/*
* When the YP server is running in DNS forwarding mode,
* the forwarder will return YPERR_NOMORE to us if it
* is unable to contact a server (i.e., it has timed out).
* The NSS_NISSERVDNS_TRYAGAIN is returned for timeout errors.
*/
case YPERR_NOMORE:
if (ismatch)
return (NSS_NISSERVDNS_TRYAGAIN);
else
return (NSS_NOTFOUND);
case YPERR_DOMAIN:
case YPERR_YPSERV:
case YPERR_BUSY:
return (NSS_TRYAGAIN);
default:
return (NSS_UNAVAIL);
}
}
/*ARGSUSED*/
void *dummy;
{
}
be->enum_keylen = 0;
return (NSS_SUCCESS);
}
void *dummy;
{
/* Nothing else we can clean up, is there? */
}
void
{
const char *first;
const char *last;
}
;
}
;
}
/*
* Don't check for an empty line because it shouldn't ever
* have made it into the YP map.
*/
}
const char *domain;
const char *map;
const char *key;
char **valp;
int *vallenp;
int *ypstatusp;
{
int ypstatus;
#if MT_UNSAFE_YP
(void) sigfillset(&newmask);
(void) mutex_lock(&one_lane);
#endif
#if MT_UNSAFE_YP
(void) mutex_unlock(&one_lane);
#endif
if (ypstatusp != 0) {
}
}
/*
* XXX special version of _nss_nis_ypmatch() for handling C2 (passwd.adjunct)
* lookups when we need a reserved port.
*/
static nss_status_t
const char *domain;
const char *map;
const char *key;
char **valp;
int *vallenp;
int *ypstatusp;
{
int ypstatus;
#if MT_UNSAFE_YP
(void) sigfillset(&newmask);
(void) mutex_lock(&one_lane);
#endif
#if MT_UNSAFE_YP
(void) mutex_unlock(&one_lane);
#endif
if (ypstatusp != 0) {
}
}
int netdb;
const char *map;
const char *key;
int *ypstatusp;
{
int vallen;
char *val;
char *free_ptr;
int parsestat;
ypstatusp)) != NSS_SUCCESS) {
return (res);
}
if (parsestat != NSS_STR_PARSE_SUCCESS) {
return (NSS_NOTFOUND);
}
if (netdb) {
}
if (parsestat == NSS_STR_PARSE_SUCCESS) {
res = NSS_SUCCESS;
} else if (parsestat == NSS_STR_PARSE_ERANGE) {
/* We won't find this otherwise, anyway */
res = NSS_NOTFOUND;
} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
return (res);
}
int netdb;
const char *map;
const char *key;
int *ypstatusp;
{
int vallen;
char *val;
char *free_ptr;
int parsestat;
return (res);
}
if (netdb) {
}
if (parsestat == NSS_STR_PARSE_SUCCESS) {
res = NSS_SUCCESS;
} else if (parsestat == NSS_STR_PARSE_ERANGE) {
/* We won't find this otherwise, anyway */
res = NSS_NOTFOUND;
} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
return (res);
}
static nss_status_t
int netdb;
{
int ypstatus;
char *free_ptr;
int parsestat;
#if MT_UNSAFE_YP
(void) sigfillset(&newmask);
(void) mutex_lock(&one_lane);
#endif
&outvallen, 0);
} else {
&outvallen, 0);
}
#if MT_UNSAFE_YP
(void) mutex_unlock(&one_lane);
#endif
return (res);
}
if (netdb) {
}
if (parsestat == NSS_STR_PARSE_SUCCESS) {
res = NSS_SUCCESS;
} else if (parsestat == NSS_STR_PARSE_ERANGE) {
/* We won't find this otherwise, anyway */
res = NSS_NOTFOUND;
} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
}
return (res);
}
void *args;
{
}
void *args;
{
}
struct cb_data {
void *args;
const char *filter;
};
/*ARGSUSED*/
static int
int instatus;
const char *inkey;
int inkeylen;
const char *inval;
int invallen;
{
return (ITER_NEXT); /* yp_all may decide otherwise... */
}
/*
* Optimization: if the entry doesn't contain the filter
* string then it can't be the entry we want, so don't
* bother looking more closely at it.
*/
return (ITER_NEXT);
}
if (res == NSS_NOTFOUND) {
return (ITER_NEXT);
} else {
return (ITER_STOP);
}
}
void *args;
const char *filter;
{
int ypall_status;
#if MT_UNSAFE_YP
(void) sigfillset(&newmask);
(void) mutex_lock(&one_lane);
#endif
#if MT_UNSAFE_YP
(void) mutex_unlock(&one_lane);
#endif
switch (ypall_status) {
case 0:
case YPERR_DOMAIN:
case YPERR_YPSERV:
case YPERR_BUSY: /* Probably never get this, but... */
return (NSS_TRYAGAIN);
default:
return (NSS_UNAVAIL);
}
}
struct XbyY_data {
int netdb;
};
static nss_status_t
const char *instr;
int instr_len;
void *a;
{
int parsestat;
}
if (parsestat == NSS_STR_PARSE_SUCCESS) {
res = NSS_SUCCESS;
} else {
res = NSS_NOTFOUND;
}
} else if (parsestat == NSS_STR_PARSE_ERANGE) {
/*
* If we got here because (*str2ent)() found that the buffer
* wasn't big enough, maybe we should quit and return erange.
* Instead we'll keep looking and eventually return "not
* found" -- it's a bug, but not an earth-shattering one.
*/
res = NSS_NOTFOUND;
} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
return (res);
}
int netdb;
const char *filter;
{
/* Now how many levels of callbacks was that? */
}
/*ARGSUSED*/
void *dummy;
{
if (be != 0) {
/* === Should change to invoke ops[ENDENT] ? */
(void) _nss_nis_endent(be, 0);
}
return (NSS_SUCCESS); /* In case anyone is dumb enough to check */
}
/* We want to lock this even if the YP routines are MT-safe */
static char *yp_domain;
const char *
{
char *domain;
/*
* This much locking is probably more "by the book" than necessary...
*/
(void) sigfillset(&newmask);
(void) mutex_lock(&yp_domain_lock);
#if MT_UNSAFE_YP
(void) mutex_lock(&one_lane);
#endif
if (yp_get_default_domain(&yp_domain) == 0) {
}
#if MT_UNSAFE_YP
(void) mutex_unlock(&one_lane);
#endif
}
(void) mutex_unlock(&yp_domain_lock);
return (domain);
}
int n_ops;
const char *enum_map;
{
const char *domain;
if ((domain = _nss_nis_domain()) == 0 ||
return (0);
}
be->enum_keylen = 0;
return ((nss_backend_t *)be);
}
/*
* This routine is used to parse lines of the form:
* name number aliases
* It returns 1 if the key in argp matches any one of the
* names in the line, otherwise 0
* Used by rpc
*/
int
int linelen)
{
/* compare name */
keyp++;
linep++;
}
return (1);
/* skip remainder of the name, if any */
linep++;
/* skip the delimiting spaces */
linep++;
/* compare with the aliases */
/*
* 1st pass: skip number
* Other passes: skip remainder of the alias name, if any
*/
linep++;
/* skip the delimiting spaces */
linep++;
/* compare with the alias name */
keyp++;
linep++;
}
return (1);
}
return (0);
}