1 /*
2  * decode_yp.c
3  *
4  * RPC "Yellow Pee".
5  *
6  * Totally untested, i don't run YP. Let me know if this works. :-)
7  *
8  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
9  *
10  * $Id: decode_yp.c,v 1.6 2001/03/15 08:33:03 dugsong Exp $
11  */
12 
13 #include "config.h"
14 
15 #include <sys/types.h>
16 #include <sys/param.h>
17 #include <rpc/rpc.h>
18 #include <rpcsvc/yp_prot.h>
19 #include <rpcsvc/yppasswd.h>
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "rpc.h"
26 #include "decode.h"
27 
28 /* XXX - <rpcsvc/yppasswd.x> varies on different systems :-( */
29 
30 struct my_passwd {
31 	char   *pw_name;
32 	char   *pw_passwd;
33 	int	pw_uid;
34 	int	pw_gid;
35 	char   *pw_gecos;
36 	char   *pw_dir;
37 	char   *pw_shell;
38 };
39 
40 struct my_yppasswd {
41 	char   *oldpass;
42 	struct my_passwd newpw;
43 };
44 
45 static bool_t
xdr_my_passwd(XDR * xdrs,struct my_passwd * objp)46 xdr_my_passwd(XDR *xdrs, struct my_passwd *objp)
47 {
48 	if (xdr_string(xdrs, &objp->pw_name, ~0) &&
49 	    xdr_string(xdrs, &objp->pw_passwd, ~0) &&
50 	    xdr_int(xdrs, &objp->pw_uid) &&
51 	    xdr_int(xdrs, &objp->pw_gid) &&
52 	    xdr_string(xdrs, &objp->pw_gecos, ~0) &&
53 	    xdr_string(xdrs, &objp->pw_dir, ~0) &&
54 	    xdr_string(xdrs, &objp->pw_shell, ~0))
55 		return (TRUE);
56 
57 	return (FALSE);
58 }
59 
60 static bool_t
xdr_my_yppasswd(XDR * xdrs,struct my_yppasswd * objp)61 xdr_my_yppasswd(XDR *xdrs, struct my_yppasswd *objp)
62 {
63 	if (xdr_string(xdrs, &objp->oldpass, ~0) &&
64 	    xdr_my_passwd(xdrs, &objp->newpw))
65 		return (TRUE);
66 
67 	return (FALSE);
68 }
69 
70 int
decode_yppasswd(u_char * buf,int len,u_char * obuf,int olen)71 decode_yppasswd(u_char *buf, int len, u_char *obuf, int olen)
72 {
73 	struct rpc_msg msg;
74 	struct my_yppasswd yp;
75 	XDR xdrs;
76 	int hdrlen;
77 
78 	if ((hdrlen = rpc_decode(buf, len, &msg)) == 0)
79 		return (0);
80 
81 	obuf[0] = '\0';
82 
83 	if (msg.rm_direction == CALL &&
84 	    msg.rm_call.cb_prog == YPPASSWDPROG &&
85 	    msg.rm_call.cb_proc == YPPASSWDPROC_UPDATE) {
86 		xdrmem_create(&xdrs, buf + hdrlen, len - hdrlen, XDR_DECODE);
87 		memset(&yp, 0, sizeof(yp));
88 		if (xdr_my_yppasswd(&xdrs, &yp)) {
89 			snprintf(obuf, olen,
90 				 "%s\n%s:%s:%d:%d:%s:%s:%s\n",
91 				 yp.oldpass, yp.newpw.pw_name,
92 				 yp.newpw.pw_passwd, yp.newpw.pw_uid,
93 				 yp.newpw.pw_gid, yp.newpw.pw_gecos,
94 				 yp.newpw.pw_dir, yp.newpw.pw_shell);
95 		}
96 		xdr_destroy(&xdrs);
97 	}
98 	return (strlen(obuf));
99 }
100 
101 int
decode_ypserv(u_char * buf,int len,u_char * obuf,int olen)102 decode_ypserv(u_char *buf, int len, u_char *obuf, int olen)
103 {
104 	struct rpc_msg msg;
105 	struct xid_map *xm;
106 	char *domain;
107 	bool_t status;
108 	XDR xdrs;
109 	int hdrlen;
110 
111 	if ((hdrlen = rpc_decode(buf, len, &msg)) == 0)
112 		return (0);
113 
114 	obuf[0] = '\0';
115 
116 	if (msg.rm_direction == CALL &&
117 	    msg.rm_call.cb_prog == YPPROG &&
118 	    msg.rm_call.cb_proc == YPPROC_DOMAIN) {
119 		xdrmem_create(&xdrs, buf + hdrlen, len - hdrlen, XDR_DECODE);
120 		domain = NULL;
121 		if (xdr_string(&xdrs, &domain, YPMAXDOMAIN)) {
122 			if ((domain = strdup(domain)) != NULL)
123 				xid_map_enter(msg.rm_xid, YPPROG, YPVERS,
124 					      YPPROC_DOMAIN, (void *) domain);
125 		}
126 		xdr_destroy(&xdrs);
127 	}
128 	else if (msg.rm_direction == REPLY &&
129 		 (xm = xid_map_find(msg.rm_xid)) != NULL) {
130 		if (msg.rm_reply.rp_stat == MSG_ACCEPTED &&
131 		    msg.acpted_rply.ar_stat == SUCCESS) {
132 			xdrmem_create(&xdrs, buf + hdrlen, len - hdrlen,
133 				      XDR_DECODE);
134 			if (xdr_bool(&xdrs, &status)) {
135 				if (status == TRUE)
136 					snprintf(obuf, olen, "%s\n",
137 						 (char *)xm->data);
138 			}
139 			xdr_destroy(&xdrs);
140 		}
141 		free(xm->data);
142 		memset(xm, 0, sizeof(*xm));
143 	}
144 	return (strlen(obuf));
145 }
146