nis_misc.c revision 61961e0f20c7637a3846bb39786bb9dffa91dfb9
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* This module contains miscellaneous library functions.
*/
#include "mt.h"
#include <string.h>
#include <syslog.h>
#include <malloc.h>
#include <tiuser.h>
#include <netdir.h>
#include <strings.h>
#include "nis_clnt.h"
#include "nis_local.h"
static void nis_sort_server_endpoints_inet(nis_server *);
extern char *handle_to_server_name(CLIENT *);
extern void *__inet_get_local_interfaces();
extern FILE *__nis_debug_file;
/* ARGSUSED */
int
{
return (1);
}
/*
* __nis_pingproc()
*
* This function will send a ping "message" to a remote server.
* It doesn't bother to see if there are any results since the ping
* is defined to be unreliable.
*/
void
{
if (! clnt)
return;
}
/*
* nis_ping()
*
* This function is used to ping all of the servers that serve a given
* directory. The point of the ping is to inform them that something
* has changed in the directory and they should go off and find what it
* is. Note that we avoid pinging ourselves for optimisation. During a
* will briefly change from server[0] to the offset corresponding to
* the new master (the old replica). When everything has settled down
* after the switch, the master will once again be in server[0] of the
* directory object. The object parameter is optional for clients
* (REQUIRED FOR SERVERS) this is the object describing the directory.
*/
void
{
nis_server **srvs;
nis_server *s, *list;
int i, ns;
if (obj) {
if (name == 0)
continue;
}
}
} else {
if (! srvs)
return;
continue;
}
}
}
}
/*
* nis_dumplog(host, name, time)
*
* This function will dump log entries from the indicated host to the
* caller. It is used by the replica servers to get the updates that have
* occurred on a directory since the indicated time.
*/
{
if (result_ptr == NULL) {
return (NULL);
}
if (! clnt) {
return (result_ptr);
}
xdr_dump_args, (char *)&da,
/*
* Now see if the RPC succeeded. Note that we have
* to check for local vs. remote errors in order to
* know whether the contents of the log_result record
* (result_ptr) are meaningful.
*/
switch (stat) {
case RPC_CANTENCODEARGS:
case RPC_CANTDECODERES:
case RPC_CANTSEND:
case RPC_CANTRECV:
case RPC_TIMEDOUT:
case RPC_INTR:
/*
* This is a local error, so just return a
* generic RPC error.
*/
break;
default:
/*
* All other return values mean that result_ptr
* already has a valid status code.
*/
break;
}
return (result_ptr);
}
/*
* nis_dump(host, name, cback)
*
* This function will dump an entire directory from the indicated host.
* It uses a callback function to minimize the memory requirements on
* the client and server.
*/
int (*cback)()) /* Callback function */
{
int err;
if (result_ptr == NULL) {
return (NULL);
}
if (!clnt) {
return (result_ptr);
}
(void) mutex_lock(&__nis_callback_lock);
NULL);
(void) mutex_unlock(&__nis_callback_lock);
return (result_ptr);
}
/*
* The value of the NIS_DUMP_TIMEOUT is applicable only for the
* dump to get initiated.
*/
if (stat != RPC_SUCCESS) {
NIS_CALLBACK, 0, clnt);
if (err < 0)
}
(void) mutex_unlock(&__nis_callback_lock);
return (result_ptr);
}
/*
* Sort server endpoints so that local addresses appear
* before remote addresses.
*/
void
{
int i;
for (i = 0; i < nsvrs; i++) {
}
}
static
int
{
}
static
int
{
}
void
{
char *t;
}
/*
* Sort a list of server endpoints so that address for local interfaces
* occur before remote interfaces. If an error occurs (e.g., no memory),
* we just clean up and return; we end up not sorting the endpoints, but
* this is just for optimization anyway.
*
* There is a lot of work in this routine, so it should not be called
* frequently.
*/
static
void
{
int i;
int j;
void *local_interfaces;
void *nch;
nch = setnetconfig();
if (nch == 0)
return;
/* find any inet entry so we can do uaddr2taddr */
}
(void) endnetconfig(nch);
return;
}
if (local_interfaces == 0) {
(void) endnetconfig(nch);
return;
}
/*
* Sort endpoints so local inet addresses are first. The
* variable 'i' points to the beginning of the array,
* and 'j' points to the end. We advance 'i' as long
* as it indexes a non-inet endpoint or a local endpoint.
* We retract 'j' as long as it indexes a non-inet endpoint
* or a remote endpoint. If either of these cases fail,
* then 'i' is pointing at a remote endpoint and 'j' is
* pointing at a local endpoint. We swap them, adjust
* the indexes, and continue. When the indexes cross
* we are done.
*/
i = 0;
j = neps - 1;
while (i < j) {
i++;
continue;
}
--j;
continue;
}
i++;
--j;
}
/* clean up */
(void) endnetconfig(nch);
}
/*
* In the pre-IPv6 code, secure RPC has a bug such that it doesn't look
* at the endpoint 'family' field when selecting an endpoint to use for
* time synchronization. In order to protect that broken code from itself,
* we set the endpoint 'proto' to 'nc_netid' (i.e., "udp6" or "tcp6")
* rather than 'nc_proto' ("udp"/"tcp") if 'nc_family' is "inet6".
*
* The __nis_netconfig2ep() and __nis_netconfig_matches_ep() service
* functions below simplify endpoint manipulation by implementing the
* rules above.
*/
void
return;
} else {
}
}
return (FALSE);
return (FALSE);
else
}
struct netconfig_list {
struct netconfig_list *next;
};
static struct netconfig_list *ncl;
struct netconfig *
{
void *nch;
struct netconfig_list *p;
return (p->nc);
}
}
nch = setnetconfig();
if (nch == 0)
return (0);
break;
}
/*
* We call getnetconfigent to allocate a copy of the
* netconfig entry.
*/
if (nc) {
p = malloc(sizeof (*p));
if (p == 0)
return (0);
ncl = p;
}
(void) endnetconfig(nch);
return (nc);
}
void
{
}
void
{
}
endpoint *
{
return (NULL);
}
return (dst);
}
void
{
if (ep) {
}
}
endpoint *
{
return (ep);
}
{
return (NULL);
}
/* LINTED pointer cast */
return ((nis_server *)
}
char *
{
char *data;
return (NULL);
return (NULL);
}
return (NULL);
}
return (dst);
}
void
{
int i;
for (i = 0; i < len; i++)
}
/*
* __nis_path
*
* Given two path strings, *from and *to, work out the list of names
* between them. The length of that path and the pointer to the list
* of pointers to the name strings are returned to the caller using
* path_length and namesp. As the names list is a pointer to a list of
* pointers, the caller must pass the address of the pointer to the
* pointer to the list of pointers, hence the unusual "char ***"
* type. It is the callers responsibility to free **namesp.
*/
{
int i;
int n;
int start;
int end;
char **names;
return (NIS_BADNAME);
/* figure out how long path is */
n = 0;
if (st == HIGHER_NAME) {
n++;
}
/* Unrecoverable error */
}
} else if (st == LOWER_NAME) {
n++;
}
/* Unrecoverable error */
}
n++; /* include actual target */
} else if (st == NOT_SEQUENTIAL) {
/* names are not sequential */
n++;
}
n++; /* include common parent */
n++;
lastdircmp = dircmp;
}
/* Unrecoverable error */
}
}
return (NIS_BADNAME);
}
return (NIS_NOMEMORY);
start = 0;
end = n;
/*
* Go through again, this time storing names.
* We shouldn't need to check the loops will terminate
* on the SAME_NAME condition as we've already checked for
* errors in the previous loop.
*/
if (st == HIGHER_NAME) {
}
} else if (st == LOWER_NAME) {
}
} else if (st == NOT_SEQUENTIAL) {
/* names are not sequential */
}
}
}
/* make sure all of the allocations were successful */
for (i = 0; i < n; i++) {
__nis_path_free(names, n);
break;
}
}
/* Set the return values */
*path_length = n;
return (NIS_SUCCESS);
}
/*
* This is a stub function for clients. There is a version of
* it in rpc.nisd that checks to see if the host is listed in
* the server list.
*/
int
{
#ifdef lint
#endif /* lint */
return (0);
}
char *call_names[] = {
"NULL",
"NIS_LOOKUP",
"NIS_ADD",
"NIS_MODIFY",
"NIS_REMOVE",
"NIS_IBLIST",
"NIS_IBADD",
"NIS_IBMODIFY",
"NIS_IBREMOVE",
"NIS_IBFIRST",
"NIS_IBNEXT",
"13",
"NIS_FINDDIRECTORY",
"NIS_STATUS",
"NIS_DUMPLOG",
"NIS_DUMP",
"NIS_CALLBACK",
"NIS_CPTIME",
"NIS_CHECKPOINT",
"NIS_PING",
"NIS_SERVSTATE",
"NIS_MKDIR",
"NIS_RMDIR",
"NIS_UPDKEYS",
};
void
{
char *name;
char *pname;
char lbuf[10];
if (proc > NIS_UPDKEYS)
else
}
void
{
}
void
{
int i;
for (i = 0; i < nattr; i++) {
if (i != 0)
}
}
void
{
}
void
{
(void) fprintf(__nis_debug_file,
"status=%s, %d object%s, [z=%d, d=%d, a=%d, c=%d]\n",
}
void
{
}