/*
* 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.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
/* system include files */
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <values.h>
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
#include <utmpx.h>
#include <sac.h>
/* listener include files */
#include "lsparam.h" /* listener parameters */
#include "lsfiles.h" /* listener files info */
#include "lserror.h" /* listener error codes */
#include "lsnlsmsg.h" /* NLPS listener protocol */
#include "lssmbmsg.h" /* MS_NET identifier */
#include "lsdbf.h" /* data base file stuff */
#include "listen.h"
/* global variables */
#ifdef DEBUGMODE
#endif
char *New_cmd_lines;
char *Server_cmd_lines;
extern int t_errno;
/*
* These global symbols are used for logging.
* Pid, NLPS_proc, and Lastmsg are significant here; the others aren't used.
*/
int Splflag = 0;
int Logmax = 0;
extern char *getenv();
static void nullfix(void);
int
{
extern int read_dbf();
char *provider;
(void)exit(1);
}
#ifdef DEBUGMODE
logmessage("NLPS: Unable to open DEBUG file");
(void)exit(1);
}
#endif
/*
* re-sync TLI structures after we were exec'ed from listener
*/
if (t_sync(0) == -1) {
logmessage("NLPS: Resynchronization of TLI failed");
(void)exit(1);
}
nlps_server();
return(0);
}
/*
* nlps_server:
*/
int
{
int size;
char **argv;
dbf_t *getdbfentry();
extern char **mkdbfargv();
logmessage("NLPS: No/bad service request received");
return(-1);
}
if (size < 0) {
logmessage("NLPS: Error returned from getrequest()");
return(-1);
}
/*
* if message is NLPS protocol...
*/
* must sleep for a short period of time to
* insure that the client received any possible
* exit response message from the listener.
*/
/*
* else if message is for the MS-NET file server...
*/
logmessage("NLPS: SMB message, server disabled in data base");
else {
}
else
logmessage("NLPS: SMB message, no data base entry");
/*
* else, message type is unknown...
*/
} else {
logmessage("NLPS: Unknown service request (ignored)");
}
/*
* the routines that start servers return only if there was an error
* and will have logged their own errors.
*/
return(-1);
}
/*
* getrequest: read in a full message. Timeout, in case the client died.
* returns: -1 = timeout or other error.
* positive number = message size.
*/
int
char *bp;
{
int size;
int flags;
extern void timeout();
short cnt;
void (*oldhanp)();
/* read in MINMSGSZ to determine type of msg */
return(-1);
}
/*
* if message is NLPS protocol...
*/
do {
logmessage("NLPS: recieve buffer not large enough");
return(-1);
}
return(-1);
}
} while (*tmp++ != '\0');
/*
* else if message is for the MS-NET file server...
*/
/* read in 28 more bytes to get count of paramter words */
return(-1);
}
tmp += 28;
size += 28;
/*
* read amount of paramater words plus word for
*/
logmessage("NLPS: recieve buffer not large enough");
return(-1);
}
return(-1);
}
logmessage("NLPS: recieve buffer not large enough");
return(-1);
}
return(-1);
}
nullfix();
/*
* else, message type is unknown...
*/
} else {
logmessage("NLPS: Unknown service request (ignored)");
return(-1);
}
(void)alarm(0);
return(size);
}
/*
* The following code is for patching a 6300 side bug. The original
* message that comes over may contain 2 null bytes which aren't
* part of the message, and if left on the stream, will poison the
* server. Peek into the stream and snarf up those bytes if they
* are there. If anything goes wrong with the I_PEEK, just continue,
* if the nulls weren't there, it'll work, and if they were, all that
* will happen is that the server will fail. Just note what happened
* in the log file.
*/
static void
nullfix(void)
{
int flags;
int ret;
/* need to ask for ctl info to avoid bug in I_PEEK code */
if (ret == -1) {
}
else if (ret == 0) {
}
else {
/* Note: junk contains "peeked" data */
/* pitch the nulls */
}
}
/*
* this represents a somewhat pathological case where
* the "2 nulls" are broken across message boundaries.
* Pitch the first and hope the next one is there
*/
if (junk[0] == 0) {
/* pitch the first */
if (ret == -1) {
}
else if (ret == 0) {
}
else {
if (junk[0] == 0) {
/* pitch the second */
}
else {
/* uh oh, server will most likely fail */
logmessage("NLPS: nullfix(): threw away a valid null byte");
}
}
}
}
}
}
}
/*
* timeout: SIGALRM signal handler. Invoked if t_rcv timed out.
* See comments about 'exit' in nlps_server().
*/
void
timeout()
{
}
/*
* nls_service: Validate and start a server requested via the NLPS protocol
*
* version 0:1 -- expect "NLPS:000:001:service_code".
*
* returns only if there was an error (either msg format, or couldn't exec)
*/
static char *badversion =
"NLPS: Unknown version of an NLPS service request: %d:%d";
static char *disabledmsg =
"NLPS: Request for service code <%s> denied, service is disabled";
static char *nlsunknown =
"NLPS: Request for service code <%s> denied, unknown service code";
/*
* Nlsversion can be used as a NLPS flag (< 0 == not nls service)
* and when >= 0, indicates the version of the NLPS protocol used
*/
int
int size;
char *bp;
{
dbf_t *getdbfentry();
extern char **mkdbfargv();
int passfd;
int i;
Nlsversion = low;
else {
return(-1);
}
/*
* common code for protocol version 0 or 2
* version 0 allows no answerback message
* version 2 allows exactly 1 answerback message
*/
}
else {
/* return is an error */
}
else {
dbp->dbf_cmd_line);
/* open pipe to pass fd through */
O_WRONLY)) < 0) {
}
logmessage("NLPS: Can't push server's modules: exit");
}
i, msgbuf);
(void)exit(2);
}
}
}
}
}
else {
}
exit(2);
} else
/* if we're still here, server didn't get exec'ed */
return(-1);
}
/*
* nls_chkmsg: validate message and return fields to caller.
* returns: TRUE == good format
* FALSE== bad format
*/
int
char *bp, *svc_code_p;
{
/* first, make sure bp is null terminated */
return(0);
/* scanf returns number of "matched and assigned items" */
}
/*
* nls_reply: send the "service request response message"
* when appropriate. (Valid if running version 2 or greater).
* Must use write(2) since unknown modules may be pushed.
*
* Message format:
* protocol_verion_# : message_code_# : message_text
*/
static void
{
/* Nlsversion = -1 for login service */
if (Nlsversion >= 2) {
}
}
/*
* common code to start a server process (for any service)
* if optional argv is given, info comes from o_argv, else pointer
* to dbf struct is used. In either case, first argument in argv is
* full pathname of server. Before exec-ing the server, the caller's
* logical address, opt and udata are added to the environment.
*/
#define NETFD 0
int
{
char *path;
char **argvp;
extern char **environ;
dbf_t *getdbfentry();
extern char **mkdbfargv();
int i;
/*
* o_argv is set during SMB service setup only, in
* which case dbp is NULL.
*/
if (o_argv) {
/* this shouldn't happen because at this point we've
already found it once */
logmessage("NLPS: SMB message, missing data base entry");
}
}
else
char *prefix;
/*
* create a utmpx entry. extra fork makes parent init,
* which will clean up the entry.
*/
logmessage("NLPS: Can't fork to create utmpx entry");
exit(2);
}
if (tmp)
exit(0); /* kill parent */
/*
* child continues processing, creating utmpx and exec'ing
* the service
*/
setpgrp();
logmessage("NLPS: Stat failed on fd 0: no line "
"field available for utmpx entry");
*device = '\0';
}
else {
/*
* MPREFIX is added to the environment by the parent
* listener process.
*/
else
}
}
/* after pushmod, tli calls are questionable? */
logmessage("NLPS: Can't push server's modules: exit");
}
i, wdbp->dbf_svc_code);
}
logmessage("NLPS: No database entry");
}
}
}
}
}
}
endpwent();
#ifdef DEBUGMODE
#endif
/* exec returns only on failure! */
logmessage("NLPS server: could not exec service");
return(-1);
}
/*
* isdigits: string version of isdigit. (See ctype(3))
*/
/* This routine is public here and used in lsdbf.c as an external */
int
isdigits(p)
register char *p;
{
if (!strlen(p))
return(0);
while (*p)
if (!isdigit(*p++))
flag = 0;
return(flag);
}
int
char *bufp;
int bytes;
int *flagp;
{
register int n;
do {
*flagp = 0;
if (n < 0) {
#ifdef DEBUGMODE
}
#endif
return(n);
}
count -= n;
bp += n;
} while (count > 0);
}
/*
* getdbfentry: Given a service code, return a pointer to the dbf_t
* entry. Return NULL if the entry doesn't exist.
* Reads the data base, one line at a time, into
* Dbf_line_buf.
*/
dbf_t *
register char *svc_code_p;
{
logmessage("NLPS: Unable to open database file");
}
&Dbf_entry.dbf_cmd_line) > 0) {
/* see if this line is the one we want (svc_code match) */
return(&Dbf_entry);
}
}
return((dbf_t *)0); /* svc code not in database */
}