/*
* 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
*/
/*
*/
/*
* This module contains the subroutines used by the server to manipulate
* objects and names.
*/
#include "mt.h"
#include <pwd.h>
#include <grp.h>
#include <syslog.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <tiuser.h>
#include <netconfig.h>
#include <netdir.h>
#include <rpc/rpcb_clnt.h>
#include <rpc/pmap_clnt.h>
#include <rpcsvc/nis_dhext.h>
#include "nis_clnt.h"
#include <sys/systeminfo.h>
#include <nsswitch.h>
/*
* send and receive buffer size used for clnt_tli_create if not specified.
* This is only used for "UDP" connection.
* This limit can be changed from the application if this value is too
* small for the application. To use the maximum value for the transport,
* set this value to 0.
*/
/*
* Static function prototypes.
*/
static struct local_names *__get_local_names(void);
/*
* nis_dir_cmp() -- the results can be read as:
* "Name 'n1' is a $result than name 'n2'"
*/
{
return (BAD_NAME);
/* In this routine we're lenient and don't require a trailing '.' */
/* so we need to ignore it if it does appear. */
/* ==== That's what the previous version did so this one does */
/* too, but why? Is this inconsistent with rest of system? */
--l1;
}
--l2;
}
result = LOWER_NAME;
}
/* Now l1 >= l2 in all cases */
if (l2 == 0) {
/* Special case for n2 == "." or "" */
return (result);
}
return (NOT_SEQUENTIAL);
}
}
return (result);
}
return (NOT_SEQUENTIAL);
}
struct principal_list {
};
struct local_names {
char *rpcdomain;
};
static struct local_names *__get_local_names1();
static struct local_names *
__get_local_names(void)
{
names = __get_local_names1();
return (names);
}
static struct local_names *
__get_local_names1(void)
{
char *t;
/* Second and subsequent calls go this way */
return (ln);
}
/* First call goes this way */
return (NULL);
}
return (ln);
/* If no dot exists, add one. */
return (ln);
/*
* Check for fully qualified hostname. If it's a fully qualified
* hostname, strip off the domain part. We always use the local
* domainname for the host principal name.
*/
if (t)
*t = 0;
t = getenv("NIS_GROUP");
if (t == NULL) {
} else {
/*
* Copy <= maximum characters from NIS_GROUP; strncpy()
* doesn't terminate, so we do that manually. #1223323
* Also check to see if it's "". If it's the null string,
* we return because we don't want to add ".domain".
*/
return (ln);
}
/* Is the group name somewhat fully-qualified? */
/* If not, we need to add ".domain" to the group */
/* truncate to make room for ".domain" */
/* concat '.' if domain doesn't already have it */
}
}
}
return (ln);
}
/*
* nis_local_group()
*
* Return's the group name of the current user.
*/
nis_local_group(void)
{
/* LOCK NOTE: Warning, after initialization, "ln" is expected */
/* to stay constant, So no need to lock here. If this assumption */
/* is changed, this code must be protected. */
if (!ln)
return (NULL);
}
/*
* __nis_nextsep_of()
*
* This internal funtion will accept a pointer to a NIS name string and
* return a pointer to the next separator occurring in it (it will point
* just past the first label). It allows for labels to be "quoted" to
* prevent the the dot character within them to be interpreted as a
* separator, also the quote character itself can be quoted by using
* it twice. If the the name contains only one label and no trailing
* dot character, a pointer to the terminating NULL is returned.
*/
__nis_nextsep_of(char *s)
{
char *d;
if (!s)
return (NULL);
for (d = s; (in_quotes && (*d != '\0')) ||
quote_quote = FALSE;
if (*d == '.')
break;
quote_quote = FALSE;
} else if (quote_quote && (*d != '"')) {
quote_quote = FALSE;
} else if (quote_quote && (*d == '"')) {
quote_quote = FALSE;
} else if (in_quotes && (*d == '"')) {
quote_quote = TRUE;
} else if (!in_quotes && (*d == '"')) {
quote_quote = TRUE;
}
}
if (quote_quote || in_quotes) {
"Mismatched quotes in %s", s);
}
return (d);
}
/*
* nis_domain_of()
*
* This internal funtion will accept a pointer to a NIS name string and
* return a pointer to the "domain" part of it.
*
* ==== We don't need nis_domain_of_r(), but should we provide one for
* uniformity?
*/
nis_domain_of(char *s)
{
char *d;
d = __nis_nextsep_of(s);
if (d == NULL)
return (NULL);
if (*d == '.')
d++;
if (*d == '\0') /* Don't return a zero length string */
return ("."); /* return root domain instead */
return (d);
}
/*
* nis_leaf_of()
*
* Returns the first label of a name. (other half of __domain_of)
*/
const nis_name s,
char *buf,
{
const char *d = __nis_nextsep_of((char *)s);
if (d == 0) {
return (0);
}
nchars = d - s;
return (0);
}
return (buf);
}
nis_leaf_of(char *s)
{
return (NULL);
}
/*
* nis_name_of()
* This internal function will remove from the NIS name, the domain
* name of the current server, this will leave the unique part in
* the name this becomes the "internal" version of the name. If this
* function returns NULL then the name we were given to resolve is
* bad somehow.
* NB: Uses static storage and this is a no-no with threads. XXX
*/
char *s, /* string with the name in it. */
char *buf,
{
char *d;
name_pos p;
#ifdef lint
#endif /* lint */
if ((!s) || (!ln))
return (NULL); /* No string, this can't continue */
return (NULL);
sl++;
}
return (buf);
}
p = nis_dir_cmp(buf, d);
/* 's' is above 'd' in the tree */
return (NULL);
/* Insert a NUL where the domain name starts in the string */
/* Don't return a zero length name */
if (buf[0] == '\0')
return (NULL);
return (buf);
}
char *s) /* string with the name in it. */
{
if (!buf)
return (NULL);
}
/*
* nis_local_directory()
*
* Return a pointer to a string with the local directory name in it.
*/
nis_local_directory(void)
{
/* LOCK NOTE: Warning, after initialization, "ln" is expected */
/* to stay constant, So no need to lock here. If this assumption */
/* is changed, this code must be protected. */
return (NULL);
}
/*
* __nis_rpc_domain()
*
* Return a pointer to a string with the rpc domain name in it.
*/
{
/* LOCK NOTE: Warning, after initialization, "ln" is expected */
/* to stay constant, So no need to lock here. If this assumption */
/* is changed, this code must be protected. */
return (NULL);
}
/*
* nis_local_host()
* Generate the principal name for this host, "hostname"+"domainname"
* unless the hostname already has "dots" in its name.
*/
nis_local_host(void)
{
/* LOCK NOTE: Warning, after initialization, "ln" is expected */
/* to stay constant, So no need to lock here. If this assumption */
/* is changed, this code must be protected. */
return (NULL);
}
/*
* nis_destroy_object()
* This function takes a pointer to a NIS object and deallocates it. This
* is the inverse of __clone_object below. It must be able to correctly
* deallocate partially allocated objects because __clone_object will call
* it if it runs out of memory and has to abort. Everything is freed,
* INCLUDING the pointer that is passed.
*/
void
{
if (obj == 0)
return;
} /* nis_destroy_object */
static void
destroy_nis_sdata(void *p)
{
}
/* XXX Why are these static ? */
/* static XDR in_xdrs, out_xdrs; */
/*
* __clone_object_r()
* This function takes a pointer to a NIS object and clones it. This
* duplicate object is now available for use in the local context.
*/
struct nis_sdata *clone_buf_ptr)
{
return (NULL);
/* Allocate a basic NIS object structure */
if (dest) {
} else
return (NULL);
/* Encode our object into the clone buffer */
(void) xdr_setpos(&in_xdrs, 0);
return (NULL);
/* Now decode the buffer into our result pointer ... */
(void) xdr_setpos(&out_xdrs, 0);
return (NULL);
/* presto changeo, a new object */
return (result);
} /* __clone_object_r */
{
} /* __clone_object */
/* Various subroutines used by the server code */
{
if (!res)
return (NULL);
/* This is ok if we are the root of roots. */
return (NULL);
}
/* Now read in the object */
xdr_destroy(&xdrs);
if (!status) {
return (NULL);
}
return (res);
}
int
char *f, /* name of the object to read */
nis_object *o) /* The object to write */
{
return (0);
}
/* Now encode the object */
xdr_destroy(&xdrs);
return (status);
}
/*
* Transport INDEPENDENT RPC code. This code assumes you
* a ping handle on top of a datagram transport.
*/
/*
* __map_addr()
*
* This is our internal function that replaces rpcb_getaddr(). We
* build our own to prevent calling netdir_getbyname() which could
* recurse to the nameservice.
*/
static char *
char *uaddr, /* RPCBIND address */
{
/*
* If using "udp", use __nisipbufsize if inbuf and outbuf are set to 0.
*/
/* for udp only */
} else {
}
if (!client)
return (NULL);
/*
* Now make the call to get the NIS service address.
* We set the retry timeout to 3 seconds so that we
* will retry a few times. Retries should be rare
* because we are usually only called when we know
* a server is available.
*/
if (clnt_st == RPC_SUCCESS) {
if (*ua == '\0') {
return (NULL);
}
return (res);
} else if (((clnt_st == RPC_PROGVERSMISMATCH) ||
(clnt_st == RPC_PROGUNAVAIL)) &&
/*
* version 3 not available. Try version 2
* The assumption here is that the netbuf
* is arranged in the sockaddr_in
* style for IP cases.
*
* Note: If the remote host doesn't support version 3,
* we assume it doesn't know IPv6 either.
*/
int protocol;
if (port != 0) {
port & 0xff);
} else
return (res);
}
if (clnt_st == RPC_TIMEDOUT)
else
return (NULL);
}
CLIENT *
char *svc_addr;
int freeaddr = 0;
/* Sanity check */
return (0);
}
/*
* Check if we have a useable interface for this address family.
* This check properly belongs in RPC (or even further down),
* but until they provide it, we roll our own.
*/
return (0);
}
if (domapaddr) {
if (svc_addr == 0)
return (0);
freeaddr = 1;
} else if (addr == 0) {
freeaddr = 1;
}
if (addr == 0) {
return (0);
}
if (clnt) {
/* make it "close on exec" */
}
if (freeaddr)
return (clnt);
}
int __nis_ss_used = 0;
/*
* nis_get_static_storage()
*
* This function is used by various functions in their effort to minimize the
* hassles of memory management in an RPC daemon. Because the service doesn't
* implement any hard limits, this function allows people to get automatically
* growing buffers that meet their storage requirements. It returns the
* pointer in the nis_sdata structure.
*
*/
void *
{
if (!bs)
return (NULL);
return (NULL);
__nis_ss_used += sz;
int size_delta;
/* check the result of malloc() first */
/* then update the statistic. */
return (NULL);
size_delta += sz;
}
}