yp_ns_proc.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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 1991-2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* This module contains the implementation for backward compatibility
* with NIS version 2 (aka YP), so that a version 3 server (aka NIS+) can
* serve a version 2 client requests [only for Sun standard maps].
* It provides the routines that the dispatch function yp_prog_svc in
*
* This module contains the Namespace manipulation procedures and is
* not supposed to access the database directly.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <netconfig.h>
#include <netdir.h>
/* "nis_proc.h" includes "nis_mt.h" */
#include "nis_proc.h"
#include <netdb.h>
#include <ctype.h>
#define ORGDIR ".org_dir."
#define ORGDIR2 "org_dir."
#define BY "by"
#define CNAME "cname"
#define CNAMELEN 5
extern int resolv_flag;
extern int resolv_pid;
extern CLIENT *resolv_client;
extern char *resolv_tp;
long err_conv_nistoyp();
int ypcheck_nisdir();
struct ypresp_maplist *ypproc_maplist_svc();
void map2table();
int serv_wart = 0;
int mail_wart_byaddr = 0;
/* to pass the column name info from map2table to cook_record */
int netid_wart = 0;
int mult_lines_wart = 0;
/* the client can handle mulitple lines of reply from ypproc_match_svc */
static nis_error
static void
cook_an_ngroup(entry_obj *, char **, int *);
static nis_error
static char *getcaller_inet();
static
int
char *map;
{
int n;
return (0);
return (1);
}
static
char *
char *domain;
{
int n;
return (0);
domain++;
if (*domain == 0)
return (0);
return (domain);
}
static
int
{
return (0);
return (1);
}
/*
* This determines whether or not the domain passed is served by this server,
* and returns a boolean.
*/
int *
{
char *domain;
return (&isserved);
if (verbose)
if (!isserved)
return (&isserved);
}
/*
* We keep a list of the domains that have been broadcasted, but that
* we don't serve so that we will only syslog a message about it
* once.
*/
struct domain_list {
char *domain;
struct domain_list *next;
};
struct domain_list *domains;
/*
* Check to see if dname is in the list of domains. As a side-effect
* we add it to the list.
*/
static
int
domain_list_check(char *dname)
{
struct domain_list *dl;
return (1);
}
}
} else if (dl != 0) {
}
return (0);
}
int *
{
char *domain;
return (&isserved);
if (verbose)
if (isserved)
return (&isserved);
else {
/*
* This case is the one in which the domain is not supported,
* and in which we are not to respond in the unsupported
* case. We are going to make an error happen to allow the
* portmapper to end his wait without the normal udp timeout
* period. The assumption here is that the only process in
* the world which is using the function in its
* no-answer-if-nack form is the portmapper, which is doing
* the krock for pseudo-broadcast. If some poor fool calls
* this function as a single-cast message, the nack case will
* look like an incomprehensible error. Sigh... (The
* traditional Unix disclaimer)
*/
if (!domain_list_check(domain)) {
"ypserv: Domain %s not supported (broadcast)",
*dname);
}
return (0);
}
}
/*
* This implements the "get master name" function.
*/
struct ypresp_master *
struct ypreq_nokey *req;
{
char *domain;
int i;
return (&resp);
}
if (verbose)
return (&resp);
}
return (&resp);
}
/* Get the information base (table) object from the database */
/*
* MEMORY POLICY: db_lookup adds dbres to the cleanup list.
* We use it and forget it.
*/
else
return (&resp);
}
(column &&
TA_SEARCHABLE))))) {
}
return (&resp);
}
entry_obj *e; /* correspoding DES entry in cred table */
char *table_name; /* fully qualified cred table name */
long *err;
{
int num_ntrees;
int all_read;
char *val;
/*
* this section handles netid for root.
* Just return the corresponding DES entry, leave up to
* cook_record_from_entry() to format the return value.
*/
return (e);
}
add_cleanup((void (*)())XFREE,
else
return (NULL);
}
/*
* Now, process the list of objects we've got to return.
* We know, we gonna return only one entry. The real reason for
* going through this is to enforce nis_return_list's censorship.
*/
2, inkey);
return (NULL);
}
return (&(ret_en_objs->EN_data));
}
struct ypresp_val *
{
int len;
char princp[1024];
int num_ntrees;
char *t, *proto;
char *col_proto = "proto";
char *domain;
int i, j, all_read;
return (&resp);
}
if (verbose) {
}
/*
* All YP requests are unauthenticated and are successful
* only if the database has nobody-read access.
*/
if (resolv_flag) { /* save real map name */
}
/* We only support one netgroup YP map, "netgroup". */
return (&resp);
}
/* Cook the ib_request */
NULL) {
return (&resp);
}
/* Get the information base (table) object from the database */
/*
* MEMORY POLICY: db_lookup adds dbres to the cleanup list.
* We use it and forget it.
*/
else
return (&resp);
}
/* there goes yp's limited knowledge of the NIS+ universe ! */
return (&resp);
}
/*
* If we are using the default key check that the the map actually
* contains this column. If not the log an informational error instead
* of proceeding to the lookup where a more serious error would be
* produced.
*/
"%s is not explicitly supported in YP "
"compatibility mode. Unsupported NIS+ tables "
"must have column named \'%s\'.",
table, DEFAULTKEY);
return (&resp);
}
}
/* Cook the nis_attr key */
/*
* ASSERT: column is never NULL,
* could be client supplied or DEFAULTKEY
*/
/*
* Do the jugglery to conform to the NIS+ convention of null
* terminated data in the database. Cannot rely on YP
* that it will always pass a null terminated key.
*/
i++;
return (&resp);
}
/* Now, do the actual lookup for an entry we want */
*proto++ = '\0';
}
/* only make the publickey.byname type of information visible */
}
if (resolv_flag &&
return (NULL); /* fwd'ed req: skip reply */
} else
else
/* bad column, attr etc. */
return (&resp);
}
/*
* Now, process the list of objects we've got to return.
* We know, we gonna return only one entry. The real reason for
* going through this is to enforce nis_return_list's censorship.
*/
2, inkey);
return (&resp);
}
/*
* This is as grungy as any code can get. The
* netgroup format of the NIS+ table is quite
* different from that in YP; for instance, we
* do not have "reverse" lookup support. We write
* the complete code here.
*/
int i = 0, len;
char *ngrp;
add_cleanup((void (*)())XFREE,
(char *)ngrp, "yp (match) mem");
while ((ret_en_objs + i) && (i < num_ntrees)) {
e = &((ret_en_objs + i)->EN_data);
len = 0;
/*
* len returned here includes the
* NULL character '\0'
*/
break;
i++;
}
if ((num_ntrees == 1) &&
YPMAXRECORD)) {
/*
* the special case of leaf netgroup,
* print comments
*/
}
} else
return (&resp);
}
e = &(ret_en_objs->EN_data);
if (netid_wart) {
netid_e = e;
if (! e) {
return (&resp);
}
}
/* construct a complete entry from all columns */
t = record;
} else {
}
if (status != NIS_SUCCESS) {
return (&resp);
}
return (&resp);
}
struct ypresp_key_val *
struct ypreq_nokey *req;
{
char *domain;
char princp[1024];
int all_readable = 0;
return (&resp);
}
if (verbose)
/*
* All YP requests are unauthenticated and are successful
* only if the database has nobody-read access.
*/
return (&resp);
}
NULL) {
return (&resp);
}
/* Get the information base (table) object from the database */
/*
* MEMORY POLICY: db_lookup adds dbres to the cleanup list.
* We use it and forget it.
*/
else
return (&resp);
}
return (&resp);
}
/*
* MEMORY POLICY on db_firstib/nextib: always call it with
* !(flags & 2), the db_*ib routines will add fnr and fnr->obj
* to the cleanup list. We never free cookie.n_bytes if the
* cookie is to be passwd to db_nextib(). db_nextib() always
* frees the cookie it is given.
*/
return (&resp);
}
do {
if (all_readable) {
break;
} else {
princp);
}
if (! ret_en_objs) {
return (&resp);
}
}
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
return (&resp);
}
e = &(ret_en_objs->EN_data);
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
goto doagain;
}
netid_wart) {
netid_e = e;
if (! e) {
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
goto doagain;
}
}
add_cleanup((void (*)())XFREE,
/* construct a complete entry from all columns */
t = &(record[0]);
if (status != NIS_SUCCESS) {
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
return (&resp);
} else {
/*
* "<key>\n\0#<cookie><int>" as the key in resp.keydat. They loose
* if they don't send the same key back to us or send it back after
* str*cpy()'ing to a new place.
*/
int enlen;
char *enval;
char *pattern = "\n\0#";
int patlen = 3;
if (netid_wart && netid_e)
e = netid_e;
"yp (first) resp.keydat.dptr");
sizeof (int);
/* skip these many bytes before getting to the cookie */
(char *)&enlen, sizeof (int));
}
if (ret_en_objs && !all_readable)
return (&resp);
}
struct ypresp_key_val *
{
int len;
char *domain;
char princp[1024];
int key_ndx;
int all_readable = 0;
return (&resp);
}
if (verbose)
/*
* All YP requests are unauthenticated and are successful
* only if the database has nobody-read access.
*/
return (&resp);
}
return (&resp);
}
/* Get the information base (table) object from the database */
/*
* MEMORY POLICY: db_lookup adds dbres to the cleanup list.
* We use it and forget it.
*/
else
return (&resp);
}
/* there goes yp's limited knowledge of the NIS+ universe ! */
return (&resp);
}
/*
* "<key>\n\0#<cookie><int>" as the key in resp.keydat. They loose
* if they haven't sent the same key back to us or sent it back after
* str*cpy()'ing to a new place.
*/
sizeof (int));
/* We got a cookie we can't understand */
return (&resp);
}
if ((*(t - 1) != '#') || (*(t -2) != '\0')) {
/* We got a cookie we can't understand */
return (&resp);
}
return (&resp);
}
do {
if (all_readable) {
break;
} else {
princp);
}
if (! ret_en_objs) {
return (&resp);
}
}
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
return (&resp);
}
e = &(ret_en_objs->EN_data);
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
goto doagain;
}
netid_wart) {
netid_e = e;
if (! e) {
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
goto doagain;
}
}
add_cleanup((void (*)())XFREE,
/* construct a complete entry from all columns */
t = &(record[0]);
if (status != NIS_SUCCESS) {
if (ret_en_objs && !all_readable)
return (&resp);
}
if (ret_en_objs && !all_readable)
return (&resp);
} else {
/*
* "<key>\n\0#<cookie><int>" as the key in resp.keydat. They loose
* if they don't send the same key back to us or send it back after
* str*cpy()'ing to a new place.
*/
int enlen;
char *enval;
char *pattern = "\n\0#";
int patlen = 3;
if (netid_wart && netid_e)
e = netid_e;
sizeof (int));
"yp (next) resp.keydat.dptr");
sizeof (int);
/* skip these many bytes before getting to the cookie */
(char *)&enlen, sizeof (int));
}
if (ret_en_objs && !all_readable)
return (&resp);
}
struct ypresp_all *
struct ypreq_nokey *req;
{
char *domain;
char princp[1024];
return (&resp);
}
if (verbose)
/*
* All YP requests are unauthenticated and are successful
* only if the database has nobody-read access.
*/
return (&resp);
}
return (&resp);
}
add_cleanup((void (*)())XFREE,
(char *)full_tblnm, "yp (all) full_tblnm");
/* Get the information base (table) object from the database */
/*
* MEMORY POLICY: db_lookup adds dbres to the cleanup list.
* We use it and forget it.
*/
else
return (&resp);
}
return (&resp);
}
/*
* Send reply from this thread without forking. An alternative
* implementation would be to create a new thread to send the
* reply; both have their complementary advantages and disadvantages:
*
* Send reply from this thread:
*
* Simpler to implement
*
* No new thread created, so probably slightly quicker
*
* No runaway resource usage (i.e., lots of threads) in
* rpc.nisd
*
* Don't have to worry about 'transp' (= rqstp->rq_xprt)
* possibly becoming invalid while a child thread is running.
*
* Send reply from a new thread:
*
* Less risk of denial-of-service if yp_all() calls use up
* all of the auto RPC mode service threads
*
* We opt for simplicity.
*/
if (!svc_sendreply(transp,
}
return (0);
}
static void
{
while (maplist) {
}
}
struct ypresp_maplist *
{
char *domain;
int namesz, i;
return (&maplist);
}
if (verbose)
domain);
return (&maplist);
}
/*
* MEMORY POLICY on db_firstib/nextib: always call it with
* !(flags & 2), the db_*ib routines will add fnr and fnr->obj
* to the cleanup list. We never free cookie.n_bytes if the
* cookie is to be passwd to db_nextib(). db_nextib() always
* frees the cookie it is given.
*/
/*
* POLICY: For each table name, the corresponding map names
* are concocted by expanding <tablename>.by<approriate_column>,
* where appropriate_column is a searchable column in the
* table that does not have the names CNAME (ignore this) or
* DEFAULTKEY (expand only to <tablename>). Idea is that the
* client MUST be able to lookup EVERY such mapname returned,
* should not return too many mapnames and should not confuse
* users by renaming conventional NIS mapnames.
*
* HACKS: As a consequence of the above policy, we must do
* something special to rename all the "auto_*" tables to
* "auto.*", suppress printing "services.byproto", print
* a new map "services.byservicename" that really looks at the
* key "name" in the services table (look at map2table() for
* the explanation of this hack), and print "mail.aliases"
* and "mail.byaddr" as the only two maps for the mail_aliases
* table.
*/
YPMAXMAP) {
continue;
}
else
continue;
char *ptr;
if (ptr)
*ptr = '.';
else
continue;
else if (strcmp("auth_name",
else
continue;
else
continue;
} else {
}
}
break;
}
} else {
}
}
}
return (&maplist);
}
/*
* This one does most of the server side work for yp_all. Of course,
* should not be generated by rpcgen. Fetches the whole database
* for the map and serializes a stream of struct ypresp_key_val's.
*/
struct ypresp_all *resp;
{
struct ypresp_key_val respdat;
int len;
int nokey = 0; /* can we isolate the key part of the entry ? */
char *t, *p = short_tblnm;
int all_readable = 0;
return (FALSE);
return (FALSE);
return (FALSE);
return (TRUE);
}
t = strchr(p, '.');
if (t)
*t = '\0';
/*
* MEMORY POLICY on db_firstib/nextib: always call it with
* !(flags & 2), the db_*ib routines will add fnr and fnr->obj
* to the cleanup list. We never free cookie.n_bytes if the
* cookie is to be passwd to db_nextib(). db_nextib() always
* frees the cookie it is given.
*/
if (all_readable)
else
if (ret_en_objs == NULL) {
continue; /* avoid the song 'n dance below */
}
return (FALSE);
return (FALSE);
if (ret_en_objs && !all_readable)
break;
}
e = &(ret_en_objs->EN_data);
if ((strcmp(p, "cred") == 0) &&
if (ret_en_objs && !all_readable)
continue;
}
if ((strcmp(p, "cred") == 0) &&
netid_wart) {
netid_e = e;
if (! e) {
FN_NOMANGLE, NULL);
if (ret_en_objs && !all_readable)
continue;
}
}
if ((resp->key_column_ndx < 0) ||
nokey = 1;
/* construct a complete entry from all columns */
t = &(record[0]);
resp->table_zobj);
if (status != NIS_SUCCESS) {
return (FALSE);
return (FALSE);
break;
}
if (! nokey) {
if (netid_wart && netid_e)
e = netid_e;
if (serv_wart &&
(strcmp(p, "services") == 0)) {
}
}
return (FALSE);
return (FALSE);
if (ret_en_objs && !all_readable)
}
return (FALSE);
return (TRUE);
}
static char *
upcase(s)
char *s;
{
char *t;
for (t = s; *t; t++)
*t = toupper(*t);
return (s);
}
/*
* Following cook_* routines are very flimsy, and should be kept static.
*/
static
struct ypresp_val *resp;
long stat;
{
}
static
struct ypresp_key_val *keyresp;
long stat;
{
}
/*
* Takes a NIS+ entry and the column separator and returns
* a reasonable looking YP record and its length.
*/
static nis_error
entry_obj *e;
char **record_dat;
int *record_len;
char *table;
{
int i, len;
char minibuf[80];
/* a rare occasion, to safeguard against garbage in e */
if (++len > YPMAXRECORD)
return (NIS_NOMEMORY);
COLVAL(3));
if (netid_wart) {
/* netid for root */
char *col, *p, *q;
return (NIS_NOMEMORY);
if ((p != NULL) &&
*q = '\0';
} else {
return (NIS_BADOBJECT);
}
} else {
/* netid for user */
COLVAL(3));
}
} else {
char *p;
if (p)
*p = 0;
}
if (mail_wart_byaddr)
else
else {
/*
* with whatever is in column 1. For other tables
* we combine all of the columns with the table
* separator.
*/
if (num_cols == 2 &&
} else {
entrydat[0] = 0;
for (i = 0; i < num_cols; i++) {
if (i) {
}
}
}
}
if (verbose)
"cook_record_from_entry: returns %s", entrydat);
/* XXX Just a hack to workaround 1083096 ??? */
(*record_len)++;
return (NIS_SUCCESS);
}
static
char *
{
int i;
char *beststring;
char *tstring;
/* determine the address of the client and store in 'addr' */
return (NULL);
return (NULL);
return (NULL);
}
/* start with first object as best address */
/* loop through other objects and see if there is a better address */
for (i = 1; i < nobj; i++) {
}
}
/* set global variable to best address found */
return (strdup(beststring));
}
/*
* This is a qsort comparison function for host objects.
* The objects are sorted by address. For hosts with the
* same address, the canonical object (cname == name) is
* sorted before the other objects with the same address.
*/
static int
const void *p1;
const void *p2;
{
int st;
int iscanon1;
int iscanon2;
/* if addresses differ, return comparison */
if (st != 0) {
/*
* If either address matches the best host address for
* the client, sort that before all others.
*/
if (best_address) {
return (-1);
return (1);
}
return (st);
}
/* determine if any objects are canonical (cname == name) */
return (0);
if (iscanon1)
return (-1);
else
return (1);
}
int len; \
\
nis_err = NIS_NOMEMORY; \
goto out_of_space; \
} else { \
} \
}
/*
* Takes an NIS+ entry and returns a reasonable looking YP host record
* and its length. We sort the host objects by host address. For
* hosts with the same address, the canonical host object (cname == name)
* is placed before the other objects with the same address. For each
* address, we print the entries for that address. If a comment appears in
* an entry, then we save it and print it after all of the host names for
* the address have been printed.
*
* The fields in a host object are:
* COLVAL(0) - official host name (canonical name)
* COLVAL(1) - host name (alias name)
* COLVAL(2) - host address
* COLVAL(3) - comment
*
* We use COLGETVAL instead COLVAL for the comment field so that if it
* is null we don't put an obnoxious "\t#" at the end.
*/
static nis_error
int num_objs;
char **record_dat;
int *record_len;
{
int i;
entry_obj *e;
char *comment;
char *ptr;
char *s;
int space;
int did_line;
char *current_address;
char *completed_entry;
char *cname;
char *name;
char *addr;
*record_len = 0;
if (num_objs == 0) {
return (NIS_SUCCESS);
} else if (num_objs > 1) {
if (best_address) {
best_address = NULL;
}
}
comment = 0; /* we save the comment field here */
did_line = 0; /* if true, we have started an entry */
current_address = "";
for (i = 0; i < num_objs; i++) {
/* new address, finish off previous entry */
if (did_line) {
if (comment) {
comment = 0;
}
}
did_line = 1;
}
}
if (!comment) {
s = COLGETVAL(3);
if (s && *s)
comment = s;
}
}
}
*completed_entry = 0; /* in case failed on partial entry */
if (verbose) {
"cook_host_record: returning \"%s\"", *record_dat);
}
return (nis_err);
}
/*
* Given an entry in the netgroup table, constructs a string
* consisting of either a member netgroup name, or a leaf
* netgroup like "(host,name,domain)".
*/
static void
entry_obj *e;
char **val;
int *vallen;
{
if (*vallen > YPMAXRECORD) {
*vallen = 1;
} else
} else {
if (*vallen > YPMAXRECORD) {
*vallen = 1;
} else
}
}
/*
* Goes through column names in table object and returns the
* index for the one that matches with the col_val passed.
* indexing is 0 thro n and returns -1 on failure.
*/
static int
char *col_val;
{
int i;
return (i);
return (-1);
}
static char *
{
char *uaddr;
return ("");
if (nc)
else
uaddr = "<no netconfig ent>";
if (nc) {
}
return (buf);
}
/*
* Hacks here onwards may go into a library, potentially
* to be inflicted on the users.
*/
long
{
switch (inerr) {
case NIS_SUCCESS:
case NIS_S_SUCCESS: return (YP_TRUE);
case NIS_NOTFOUND:
case NIS_S_NOTFOUND: return (YP_FALSE);
case NIS_NAMEUNREACHABLE:
case NIS_NOTSEARCHABLE:
case NIS_UNKNOWNOBJ: return (YP_NODOM);
case NIS_NOSUCHTABLE: return (YP_NOMAP);
case NIS_BADOBJECT:
case NIS_NOMEMORY: return (YP_YPERR);
default: return (YP_YPERR);
}
}
/*
* the most naive way and finds out if the corresponding
* NIS+ directory is served by this server.
*/
int
char *dname;
{
/*
* MEMORY POLICY: __directory_object maintains a cache and
* returns a pointer to an entry into it. We do not free
* anything here.
*/
return (status == NIS_SUCCESS);
}
/*
* A little different from ypcheck_nisdir. This one attempts to
* get the nis_object for the "ORGDIR.<domainname>[.]" directory.
*/
char *dname;
nis_object **z_obj;
{
int len;
/* don't bother who's master */
/*
* MEMORY POLICY: __directory_object maintains a cache and
* returns a pointer to an entry into it. We do not free
* anything here.
*/
return (status);
}
/*
* Supply an NIS style mapname and get back pointers to the
* names of corresponding table in NIS+ and the column to
* search. Does not make any guarantees that the table
*/
void
char *xx_mapname;
char **xx_table;
char **xx_column;
{
memset(c, 0, NIS_MAXATTRNAME);
*xx_table = t;
*xx_column = c;
serv_wart = 0;
netid_wart = 0;
mult_lines_wart = 0;
if (verbose)
/*
* This is a special and weird case.
* We have to be compatible with past mistakes
* when some ??????? built the services.byname map
*/
strcpy(t, "services");
strcpy(c, "port");
serv_wart = 1;
if (verbose)
return;
}
/*
* This is even more special and weird case.
* We are trying to be nice to the YP clients by
* giving a map they can match on using the key
* the match only on "service" or "port" as
* the key too.
*/
strcpy(t, "services");
strcpy(c, "name");
serv_wart = 1;
if (verbose)
return;
}
strcpy(t, "cred");
strcpy(c, "auth_name");
if (verbose)
return;
}
strcpy(t, "cred");
strcpy(c, "auth_name");
netid_wart = 1;
if (verbose)
return;
}
strcpy(t, "mail_aliases");
mail_wart_byaddr = 1;
} else /* if (strcmp(xx_mapname, "mail.aliases) == 0) */ {
mail_wart_byaddr = 0;
}
if (verbose)
return;
}
/*
* First check for maps of type X.byY and then replace
* all dots by _
*/
char *tmp;
tmp = p;
p += 2;
if (*p == NULL) {
/* BY was really a name */
p = NULL;
} else {
*tmp = '\0';
}
} else {
p = NULL;
}
/* replace the other dots by _ */
*tmp = '_';
}
strcpy(t, xx_mapname);
/* only the gethostbyYY client backends can handle multiple lines */
if (strcmp(t, "hosts") == 0)
mult_lines_wart = 1;
if (p)
strcpy(c, p);
strcpy(c, NGROUPNAME);
else
/*
* POLICY: The default column for all maps that want to
* use the backward compatibility and are not among the
* privileged 12 must be DEFAULTKEY. The 12 are: passwd,
* group, hosts, networks, services, rpc, mail_aliases,
* ethers, protocols, netmasks, publickey and bootparams.
*/
strcpy(c, DEFAULTKEY);
if (verbose)
}