File: decode_yp.c

package info (click to toggle)
dsniff 2.4b1+debian-22
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 1,808 kB
  • sloc: ansic: 10,785; sh: 152; makefile: 116
file content (145 lines) | stat: -rw-r--r-- 3,240 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * decode_yp.c
 *
 * RPC "Yellow Pee".
 *
 * Totally untested, i don't run YP. Let me know if this works. :-)
 *
 * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
 *
 * $Id: decode_yp.c,v 1.6 2001/03/15 08:33:03 dugsong Exp $
 */

#include "config.h"

#include <sys/types.h>
#include <sys/param.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/yppasswd.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "rpc.h"
#include "decode.h"

/* XXX - <rpcsvc/yppasswd.x> varies on different systems :-( */

struct my_passwd {
	char   *pw_name;
	char   *pw_passwd;
	int	pw_uid;
	int	pw_gid;
	char   *pw_gecos;
	char   *pw_dir;
	char   *pw_shell;
};

struct my_yppasswd {
	char   *oldpass;
	struct my_passwd newpw;
};

static bool_t
xdr_my_passwd(XDR *xdrs, struct my_passwd *objp)
{
	if (xdr_string(xdrs, &objp->pw_name, ~0) &&
	    xdr_string(xdrs, &objp->pw_passwd, ~0) &&
	    xdr_int(xdrs, &objp->pw_uid) &&
	    xdr_int(xdrs, &objp->pw_gid) &&
	    xdr_string(xdrs, &objp->pw_gecos, ~0) &&
	    xdr_string(xdrs, &objp->pw_dir, ~0) &&
	    xdr_string(xdrs, &objp->pw_shell, ~0))
		return (TRUE);

	return (FALSE);
}

static bool_t
xdr_my_yppasswd(XDR *xdrs, struct my_yppasswd *objp)
{
	if (xdr_string(xdrs, &objp->oldpass, ~0) &&
	    xdr_my_passwd(xdrs, &objp->newpw))
		return (TRUE);
	
	return (FALSE);
}

int
decode_yppasswd(u_char *buf, int len, u_char *obuf, int olen)
{
	struct rpc_msg msg;
	struct my_yppasswd yp;
	XDR xdrs;
	int hdrlen;
	
	if ((hdrlen = rpc_decode(buf, len, &msg)) == 0)
		return (0);

	obuf[0] = '\0';
	
	if (msg.rm_direction == CALL &&
	    msg.rm_call.cb_prog == YPPASSWDPROG &&
	    msg.rm_call.cb_proc == YPPASSWDPROC_UPDATE) {
		xdrmem_create(&xdrs, buf + hdrlen, len - hdrlen, XDR_DECODE);
		memset(&yp, 0, sizeof(yp));
		if (xdr_my_yppasswd(&xdrs, &yp)) {
			snprintf(obuf, olen,
				 "%s\n%s:%s:%d:%d:%s:%s:%s\n",
				 yp.oldpass, yp.newpw.pw_name,
				 yp.newpw.pw_passwd, yp.newpw.pw_uid,
				 yp.newpw.pw_gid, yp.newpw.pw_gecos,
				 yp.newpw.pw_dir, yp.newpw.pw_shell);
		}
		xdr_destroy(&xdrs);
	}
	return (strlen(obuf));
}

int
decode_ypserv(u_char *buf, int len, u_char *obuf, int olen)
{
	struct rpc_msg msg;
	struct xid_map *xm;
	char *domain;
	bool_t status;
	XDR xdrs;
	int hdrlen;
	
	if ((hdrlen = rpc_decode(buf, len, &msg)) == 0)
		return (0);

	obuf[0] = '\0';
	
	if (msg.rm_direction == CALL &&
	    msg.rm_call.cb_prog == YPPROG &&
	    msg.rm_call.cb_proc == YPPROC_DOMAIN) {
		xdrmem_create(&xdrs, buf + hdrlen, len - hdrlen, XDR_DECODE);
		domain = NULL;
		if (xdr_string(&xdrs, &domain, YPMAXDOMAIN)) {
			if ((domain = strdup(domain)) != NULL)
				xid_map_enter(msg.rm_xid, YPPROG, YPVERS,
					      YPPROC_DOMAIN, (void *) domain);
		}
		xdr_destroy(&xdrs);
	}
	else if (msg.rm_direction == REPLY &&
		 (xm = xid_map_find(msg.rm_xid)) != NULL) {
		if (msg.rm_reply.rp_stat == MSG_ACCEPTED &&
		    msg.acpted_rply.ar_stat == SUCCESS) {
			xdrmem_create(&xdrs, buf + hdrlen, len - hdrlen,
				      XDR_DECODE);
			if (xdr_bool(&xdrs, &status)) {
				if (status == TRUE)
					snprintf(obuf, olen, "%s\n",
						 (char *)xm->data);
			}
			xdr_destroy(&xdrs);
		}
		free(xm->data);
		memset(xm, 0, sizeof(*xm));
	}
	return (strlen(obuf));
}