/*
* Copyright(c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#endif /* LIBC_SCCS and not lint */
#if 0
#endif
/* Extern */
#include "port_before.h"
#include <stdio.h>
#include <ctype.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <utmp.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <irs.h>
#include <isc/memcluster.h>
#include <isc/irpmarshall.h>
#include "port_after.h"
#ifndef HAVE_STRNDUP
#endif
/* See big comment at bottom of irpmarshall.h for description. */
#ifdef WANT_IRS_PW
/* +++++++++++++++++++++++++ struct passwd +++++++++++++++++++++++++ */
/*%
* int irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len)
*
* notes: \li
*
* See irpmarshall.h
*
* return: \li
*
* 0 on sucess, -1 on failure.
*
*/
int
const char *pwClass;
return (-1);
}
#ifdef HAVE_PW_CHANGE
#else
pwChange[0] = '0';
#endif
#ifdef HAVE_PW_EXPIRE
#else
pwExpire[0] = '0';
#endif
#ifdef HAVE_PW_CLASS
#else
pwClass = "";
#endif
return (0);
}
return (-1);
}
return (-1);
}
}
return (0);
}
/*%
* int irp_unmarshall_pw(struct passwd *pw, char *buffer)
*
* notes: \li
*
* See irpmarshall.h
*
* return: \li
*
* 0 on success, -1 on failure
*
*/
int
char *p;
long t;
p = buffer;
/* pw_name field */
goto error;
}
/* pw_passwd field */
goto error;
}
/* pw_uid field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
if ((long) pwuid != t) { /*%< value must have been too big. */
goto error;
}
/* pw_gid field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
if ((long)pwgid != t) { /*%< value must have been too big. */
goto error;
}
/* pw_class field */
goto error;
}
/* pw_change field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
if ((long)pwchange != t) { /*%< value must have been too big. */
goto error;
}
/* pw_expire field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
if ((long) pwexpire != t) { /*%< value must have been too big. */
goto error;
}
/* pw_gecos field */
goto error;
}
/* pw_dir field */
goto error;
}
/* pw_shell field */
goto error;
}
#ifdef HAVE_PW_CHANGE
#endif
#ifdef HAVE_PW_CLASS
#endif
#ifdef HAVE_PW_EXPIRE
#endif
return (0);
return (-1);
}
/* ------------------------- struct passwd ------------------------- */
#endif /* WANT_IRS_PW */
/* +++++++++++++++++++++++++ struct group +++++++++++++++++++++++++ */
/*%
* int irp_marshall_gr(const struct group *gr, char **buffer, size_t *len)
*
* notes: \li
*
* See irpmarshall.h.
*
* return: \li
*
* 0 on success, -1 on failure
*/
int
return (-1);
}
#ifndef MISSING_GR_PASSWD
#else
need++;
#endif
return (0);
}
return (-1);
}
return (-1);
}
}
#ifndef MISSING_GR_PASSWD
#endif
return (0);
}
/*%
* int irp_unmarshall_gr(struct group *gr, char *buffer)
*
* notes: \li
*
* See irpmarshall.h
*
* return: \li
*
* 0 on success and -1 on failure.
*
*/
int
char *p, *q;
long t;
char *tb;
return (-1);
}
p = buffer;
/* gr_name field */
goto error;
}
/* gr_passwd field */
goto error;
}
/* gr_gid field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
if ((long) grgid != t) { /*%< value must have been too big. */
goto error;
}
/* gr_mem field. Member names are separated by commas */
if (q == NULL) {
goto error;
}
goto error;
}
p = q + 1;
#ifndef MISSING_GR_PASSWD
#endif
return (0);
return (-1);
}
/* ------------------------- struct group ------------------------- */
/* +++++++++++++++++++++++++ struct servent +++++++++++++++++++++++++ */
/*%
* int irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len)
*
* notes: \li
*
* See irpmarshall.h
*
* return: \li
*
* 0 on success, -1 on failure.
*
*/
int
short realport;
return (-1);
}
/* the int s_port field is actually a short in network order. We
want host order to make the marshalled data look correct */
return (0);
}
return (-1);
}
return (-1);
}
}
return (0);
}
/*%
* int irp_unmarshall_sv(struct servent *sv, char *buffer)
*
* notes: \li
*
* See irpmarshall.h
*
* return: \li
*
* 0 on success, -1 on failure.
*
*/
int
char *p, *q;
short svport;
long t;
char *tb;
return (-1);
p = buffer;
/* s_name field */
goto error;
}
/* s_aliases field */
if (q == NULL) {
goto error;
}
goto error;
}
p = q + 1;
/* s_port field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
svport = (short)t;
if ((long) svport != t) { /*%< value must have been too big. */
goto error;
}
/* s_proto field */
goto error;
}
return (0);
free_array(aliases, 0);
return (-1);
}
/* ------------------------- struct servent ------------------------- */
/* +++++++++++++++++++++++++ struct protoent +++++++++++++++++++++++++ */
/*%
* int irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len)
*
* notes: \li
*
* See irpmarshall.h
*
* return: \li
*
* 0 on success and -1 on failure.
*
*/
int
return (-1);
}
return (0);
}
return (-1);
}
return (-1);
}
}
return (0);
}
/*%
* int irp_unmarshall_pr(struct protoent *pr, char *buffer)
*
* notes: \li
*
* See irpmarshall.h
*
* return: \li
*
* 0 on success, -1 on failure
*
*/
char *p, *q;
int prproto;
long t;
char *tb;
return (-1);
}
p = buffer;
/* p_name field */
goto error;
}
/* p_aliases field */
if (q == NULL) {
goto error;
}
goto error;
}
p = q + 1;
/* p_proto field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
prproto = (int)t;
if ((long) prproto != t) { /*%< value must have been too big. */
goto error;
}
return (0);
free_array(aliases, 0);
return (-1);
}
/* ------------------------- struct protoent ------------------------- */
/* +++++++++++++++++++++++++ struct hostent +++++++++++++++++++++++++ */
/*%
* int irp_marshall_ho(struct hostent *ho, char **buffer, size_t *len)
*
* notes: \li
*
* See irpmarshall.h.
*
* return: \li
*
* 0 on success, -1 on failure.
*
*/
int
char **av;
char *p;
int addrlen;
int malloced = 0;
return (-1);
}
switch(ho->h_addrtype) {
case AF_INET:
break;
case AF_INET6:
break;
default:
return (-1);
}
/* we determine an upper bound on the string length needed, not an
exact length. */
return (0);
}
return (-1);
}
return (-1);
}
malloced = 1;
}
goto error;
}
p += strlen(p);
}
return (0);
if (malloced) {
}
return (-1);
}
/*%
* int irp_unmarshall_ho(struct hostent *ho, char *buffer)
*
* notes: \li
*
* See irpmarshall.h.
*
* return: \li
*
* 0 on success, -1 on failure.
*
*/
int
char *p, *q, *r;
int hoaddrtype;
int holength;
long t;
char *name;
char *tb;
char **alist;
int addrcount;
return (-1);
}
p = buffer;
/* h_name field */
goto error;
}
/* h_aliases field */
if (q == NULL) {
goto error;
}
goto error;
}
p = q + 1;
/* h_addrtype field */
goto error;
}
else
goto error;
/* h_length field */
goto error;
}
if (*tb) {
goto error; /*%< junk in value */
}
holength = (int)t;
if ((long) holength != t) { /*%< value must have been too big. */
goto error;
}
/* h_addr_list field */
if (q == NULL)
goto error;
/* count how many addresss are in there */
if (q > p + 1) {
for (addrcount = 1, r = p ; r != q ; r++) {
if (*r == COMMA)
addrcount++;
}
} else {
addrcount = 0;
}
if (hohaddrlist == NULL) {
goto error;
}
alist = hohaddrlist;
for (t = 0, r = p ; r != q ; p = r + 1, t++) {
char saved;
while (r != q && *r != COMMA) r++;
saved = *r;
*r = 0x0;
goto error;
}
goto error;
*r = saved;
}
return (0);
free_array(hohaddrlist, 0);
free_array(aliases, 0);
return (-1);
}
/* ------------------------- struct hostent------------------------- */
/* +++++++++++++++++++++++++ struct netgrp +++++++++++++++++++++++++ */
/*%
* int irp_marshall_ng(const char *host, const char *user,
* const char *domain, char *buffer, size_t *len)
*
* notes: \li
*
* See note for irp_marshall_ng_start
*
* return: \li
*
* 0 on success, 0 on failure.
*
*/
int
return (-1);
}
return (0);
return (-1);
}
return (-1);
}
}
(*buffer)[0] = '(';
return (0);
}
/* ---------- */
/*%
* int irp_unmarshall_ng(const char **host, const char **user,
* const char **domain, char *buffer)
*
* notes: \li
*
* Unpacks the BUFFER into 3 character arrays it allocates and assigns
* to *HOST, *USER and *DOMAIN. If any field of the value is empty,
* then the corresponding parameter value will be set to NULL.
*
* return: \li
*
* 0 on success and -1 on failure.
*/
int
char *buffer)
{
char *p, *q;
return (-1);
}
p = buffer;
while (isspace((unsigned char)*p)) {
p++;
}
if (*p != '(') {
goto error;
}
q = p + 1;
while (*q && *q != fieldsep)
q++;
if (!*q) {
goto error;
} else if (q > p + 1) {
}
p = q + 1;
if (!*p) {
goto error;
} else if (*p != fieldsep) {
q = p + 1;
while (*q && *q != fieldsep)
q++;
if (!*q) {
goto error;
}
} else {
p++;
}
if (!*p) {
goto error;
} else if (*p != ')') {
q = p + 1;
while (*q && *q != ')')
q++;
if (!*q) {
goto error;
}
}
return (0);
return (-1);
}
/* ------------------------- struct netgrp ------------------------- */
/* +++++++++++++++++++++++++ struct nwent +++++++++++++++++++++++++ */
/*%
* int irp_marshall_nw(struct nwent *ne, char **buffer, size_t *len)
*
* notes: \li
*
* See at top.
*
* return: \li
*
* 0 on success and -1 on failure.
*
*/
int
return (-1);
}
return (-1);
}
return (0);
}
return (-1);
}
return (-1);
}
}
return (0);
}
/*%
* int irp_unmarshall_nw(struct nwent *ne, char *buffer)
*
* notes: \li
*
* See note up top.
*
* return: \li
*
* 0 on success and -1 on failure.
*
*/
int
char *p, *q;
int naddrtype;
long nnet;
int bits;
char *tb;
goto error;
}
p = buffer;
/* n_name field */
goto error;
}
/* n_aliases field. Aliases are separated by commas */
if (q == NULL) {
goto error;
}
goto error;
}
p = q + 1;
/* h_addrtype field */
goto error;
}
else
goto error;
/* n_net field */
goto error;
}
nnet = 0;
if (bits < 0) {
goto error;
}
/* nnet = ntohl(nnet); */ /* keep in network order for nwent */
goto error;
}
return (0);
free_array(aliases, 0);
return (-1);
}
/* ------------------------- struct nwent ------------------------- */
/* +++++++++++++++++++++++++ struct netent +++++++++++++++++++++++++ */
/*%
* int irp_marshall_ne(struct netent *ne, char **buffer, size_t *len)
*
* notes: \li
*
* See at top.
*
* return: \li
*
* 0 on success and -1 on failure.
*
*/
int
long nval;
return (-1);
}
return (-1);
}
return (0);
}
return (-1);
}
return (-1);
}
}
return (0);
}
/*%
* int irp_unmarshall_ne(struct netent *ne, char *buffer)
*
* notes: \li
*
* See note up top.
*
* return: \li
*
* 0 on success and -1 on failure.
*
*/
int
char *p, *q;
int naddrtype;
long nnet;
int bits;
char *tb;
goto error;
}
p = buffer;
/* n_name field */
goto error;
}
/* n_aliases field. Aliases are separated by commas */
if (q == NULL) {
goto error;
}
goto error;
}
p = q + 1;
/* h_addrtype field */
goto error;
}
else
goto error;
/* n_net field */
goto error;
}
if (bits < 0) {
goto error;
}
return (0);
free_array(aliases, 0);
return (-1);
}
/* ------------------------- struct netent ------------------------- */
/* =========================================================================== */
/*%
* static char ** splitarray(const char *buffer, const char *buffend, char delim)
*
* notes: \li
*
* Split a delim separated astring. Not allowed
* to have two delims next to each other. BUFFER points to begining of
* string, BUFFEND points to one past the end of the string
* (i.e. points at where the null byte would be if null
* terminated).
*
* return: \li
*
* Returns a malloced array of pointers, each pointer pointing to a
* malloced string. If BUFEER is an empty string, then return values is
* array of 1 pointer that is NULL. Returns NULL on failure.
*
*/
static char **
const char *p, *q;
int count = 0;
char **aptr;
return (NULL);
return (NULL);
return (NULL);
/* count the number of field and make sure none are empty */
if (*q == delim) {
return (NULL);
}
count++;
}
}
}
if (count > 0) {
count++ ; /*%< for NULL at end */
return (NULL);
}
/* nothing */;
p = q;
aptr++;
}
} else {
return (NULL);
}
}
return (arr);
}
/*%
* static size_t joinlength(char * const *argv)
*
* return: \li
*
* the number of bytes in all the arrays pointed at
* by argv, including their null bytes(which will usually be turned
* into commas).
*
*
*/
static size_t
int len = 0;
argv++;
}
return (len);
}
/*%
* int joinarray(char * const *argv, char *buffer, char delim)
*
* notes: \li
*
* Copy all the ARGV strings into the end of BUFFER
* separating them with DELIM. BUFFER is assumed to have
* enough space to hold everything and to be already null-terminated.
*
* return: \li
*
* 0 unless argv or buffer is NULL.
*
*
*/
static int
char * const *p;
return (-1);
}
if (*(p + 1) != NULL) {
}
}
return (0);
}
/*%
* static char * getfield(char **res, size_t reslen, char **ptr, char delim)
*
* notes: \li
*
* Stores in *RES, which is a buffer of length RESLEN, a
* copy of the bytes from *PTR up to and including the first
* instance of DELIM. If *RES is NULL, then it will be
* assigned a malloced buffer to hold the copy. *PTR is
* modified to point at the found delimiter.
*
* return: \li
*
* If there was no delimiter, then NULL is returned,
* otherewise *RES is returned.
*
*/
static char *
char *q;
return (NULL);
}
if (q == NULL) {
return (NULL);
} else {
} else {
return (NULL);
} else {
}
}
*ptr = q + 1;
}
return (*res);
}
#ifndef HAVE_STRNDUP
/*
* static char * strndup(const char *str, size_t len)
*
* notes: \li
*
* like strdup, except do len bytes instead of the whole string. Always
* null-terminates.
*
* return: \li
*
* The newly malloced string.
*
*/
static char *
if (p == NULL)
return (NULL);
p[len] = 0x0;
return (p);
}
#endif
#if WANT_MAIN
/*%
* static int strcmp_nws(const char *a, const char *b)
*
* notes: \li
*
* do a strcmp, except uneven lengths of whitespace compare the same
*
* return: \li
*
*/
static int
strcmp_nws(const char *a, const char *b) {
while (*a && *b) {
do {
a++;
} while (isspace(*a));
do {
b++;
} while (isspace(*b));
}
if (*a < *b)
return (-1);
else if (*a > *b)
return (1);
a++;
b++;;
}
if (*a == *b)
return (0);
else if (*a > *b)
return (1);
else
return (-1);
}
#endif
/*%
* static void free_array(char **argv, size_t entries)
*
* notes: \li
*
* Free argv and each of the pointers inside it. The end of
* the array is when a NULL pointer is found inside. If
* entries is > 0, then NULL pointers inside the array do
* not indicate the end of the array.
*
*/
static void
char **p = argv;
return;
while ((useEntries && entries > 0U) || *p) {
if (*p)
free(*p);
p++;
if (useEntries)
entries--;
}
}
/* ************************************************** */
#if WANT_MAIN
/*% takes an option to indicate what sort of marshalling(read the code) and
an argument. If the argument looks like a marshalled buffer(has a ':'
embedded) then it's unmarshalled and the remarshalled and the new string
is compared to the old one.
*/
int
char *b = &buffer[0];
char option;
exit(1);
argv++;
argc--;
#if 0
{
char buff[10];
printf("field: \"%s\"\n", q);
p++;
}
printf("p is now \"%s\"\n", p);
}
#endif
#if 0
{
argv[2][0]);
char **p;
if (x == NULL)
printf("split failed\n");
printf("\"%s\"\n", *p);
}
}
#endif
#if 1
switch(option) {
case 'n': {
int i;
printf("Unmarhsalling failed\n");
exit(1);
}
printf("Aliases:");
} else {
8 :
16 :
24 : -1)));
printf("Marshalling failed\n");
}
printf("%s\n", b);
}
break;
}
case 'r': {
int i;
char *buff;
char *ngname;
argv[1]) != 0) {
printf("unmarshall failed\n");
exit(1);
}
for (i = 0 ; i < entries ; i++)
printf("\t\"%s\" : \"%s\" : \"%s\"\n",
printf("}\n\n\n");
for (i = 0 ; i < entries ; i++)
for (i = 0 ; i < entries ; i++) {
&size) != 0)
printf("next marshalling failed.\n");
}
printf("compare failed:\n\t%s\n\t%s\n",
} else {
printf("compare ok\n");
}
} else {
char *h, *u, *d, *buff;
/* run through two times. First to figure out how
much of a buffer we need. Second to do the
actual marshalling */
while (getnetgrent(&h, &u, &d) == 1)
printf("Marshalling start failed\n");
while (getnetgrent(&h, &u, &d) == 1) {
!= 0) {
printf("Marshalling failed\n");
}
}
endnetgrent();
}
break;
}
case 'h': {
int i;
printf("unmarshall failed\n");
exit(1);
}
printf("\nAddr Type: \"%s\"\n",
for (i = 0 ; he.h_addr_list[i] != 0 ; i++) {
}
printf("\n\n");
printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
} else {
printf("compare ok\n");
}
} else {
perror("gethostbyname");
exit(1);
}
printf("irp_marshall_ho failed\n");
exit(1);
}
}
break;
}
case 's': {
printf("unmarshall failed\n");
}
printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
} else {
printf("compare ok\n");
}
} else {
perror("getservent");
exit(1);
}
printf("irp_marshall_sv failed\n");
exit(1);
}
}
break;
}
case 'g': {
printf("unmarshall failed\n");
}
printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
} else {
printf("compare ok\n");
}
} else {
perror("getgrnam");
exit(1);
}
printf("irp_marshall_gr failed\n");
exit(1);
}
}
break;
}
case 'p': {
printf("unmarshall failed\n");
exit(1);
}
printf("User: \"%s\"\nPasswd: \"%s\"\nUid: %ld\nGid: %ld\n",
printf("Class: \"%s\"\nChange: %ld\nGecos: \"%s\"\n",
printf("Shell: \"%s\"\nDirectory: \"%s\"\n",
printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
} else {
printf("compare ok\n");
}
} else {
perror("getpwnam");
exit(1);
}
printf("irp_marshall_pw failed\n");
exit(1);
}
}
break;
}
default:
break;
}
#endif
return (0);
}
#endif
/*! \file */