81b692845e2da0e6e39524a7238b537ce53ac085
[nfs-utils.git] / utils / rquotad / rquota_svc.c
1 /*
2  * QUOTA    An implementation of the diskquota system for the LINUX
3  *          operating system. QUOTA is implemented using the BSD systemcall
4  *          interface as the means of communication with the user level.
5  *          Should work for all filesystems because of integration into the
6  *          VFS layer of the operating system.
7  *          This is based on the Melbourne quota system wich uses both user and
8  *          group quota files.
9  *
10  *          This part accepts the rquota rpc-requests.
11  *
12  * Version: $Id: rquota_svc.c,v 2.6 1996/11/17 16:59:46 mvw Exp mvw $
13  *
14  * Author:  Marco van Wieringen <mvw@planets.elm.net>
15  *
16  *          This program is free software; you can redistribute it and/or
17  *          modify it under the terms of the GNU General Public License
18  *          as published by the Free Software Foundation; either version
19  *          2 of the License, or (at your option) any later version.
20  */
21 #include "config.h"
22
23 #ifdef HAVE_TCP_WRAPPER
24 #include "tcpwrapper.h"
25 #endif
26
27 #include <unistd.h>
28 #include <rpc/rpc.h>
29 #include "rquota.h"
30 #include <stdlib.h>
31 #include <rpc/pmap_clnt.h>
32 #include <string.h>
33 #include <memory.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <syslog.h>
37
38 #ifdef __STDC__
39 #define SIG_PF void(*)(int)
40 #endif
41
42 extern getquota_rslt *rquotaproc_getquota_1(getquota_args *argp,
43                                             struct svc_req *rqstp);
44 extern getquota_rslt *rquotaproc_getactivequota_1(getquota_args *argp,
45                                                   struct svc_req *rqstp);
46 extern getquota_rslt *rquotaproc_getquota_2(ext_getquota_args *argp,
47                                             struct svc_req *rqstp);
48 extern getquota_rslt *rquotaproc_getactivequota_2(ext_getquota_args *argp,
49                                                   struct svc_req *rqstp);
50
51 /*
52  * Global authentication credentials.
53  */
54 struct authunix_parms *unix_cred;
55
56 static void rquotaprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
57 {
58    union {
59       getquota_args rquotaproc_getquota_1_arg;
60       getquota_args rquotaproc_getactivequota_1_arg;
61    } argument;
62    char *result;
63    xdrproc_t xdr_argument, xdr_result;
64    char *(*local)(char *, struct svc_req *);
65
66 #ifdef HAVE_TCP_WRAPPER
67    /* remote host authorization check */
68    if (!check_default("rquotad", svc_getcaller(transp),
69                       rqstp->rq_proc, (u_long) 0)) {
70          svcerr_auth (transp, AUTH_FAILED);
71          return;
72    }
73 #endif
74
75    /*
76     * Don't bother authentication for NULLPROC.
77     */
78    if (rqstp->rq_proc == NULLPROC) {
79       (void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *)NULL);
80       return;
81    }
82
83    /*
84     * First get authentication.
85     */
86    switch (rqstp->rq_cred.oa_flavor) {
87       case AUTH_UNIX:
88          unix_cred = (struct authunix_parms *)rqstp->rq_clntcred;
89          break;
90       case AUTH_NULL:
91       default:
92          svcerr_weakauth(transp);
93          return;
94    }
95
96    switch (rqstp->rq_proc) {
97       case RQUOTAPROC_GETQUOTA:
98          xdr_argument = (xdrproc_t) xdr_getquota_args;
99          xdr_result = (xdrproc_t) xdr_getquota_rslt;
100          local = (char *(*)(char *, struct svc_req *)) rquotaproc_getquota_1;
101          break;
102
103       case RQUOTAPROC_GETACTIVEQUOTA:
104          xdr_argument = (xdrproc_t) xdr_getquota_args;
105          xdr_result = (xdrproc_t) xdr_getquota_rslt;
106          local = (char *(*)(char *, struct svc_req *)) rquotaproc_getactivequota_1;
107          break;
108
109       default:
110          svcerr_noproc(transp);
111          return;
112    }
113
114    (void) memset((char *)&argument, 0, sizeof (argument));
115    if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
116       svcerr_decode(transp);
117       return;
118    }
119    result = (*local)((char *)&argument, rqstp);
120    if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
121       svcerr_systemerr(transp);
122    }
123
124    if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
125       syslog(LOG_ERR, "unable to free arguments");
126       exit(1);
127    }
128    return;
129 }
130
131 static void rquotaprog_2(struct svc_req *rqstp, register SVCXPRT *transp)
132 {
133    union {
134       ext_getquota_args rquotaproc_getquota_2_arg;
135       ext_getquota_args rquotaproc_getactivequota_2_arg;
136    } argument;
137    char *result;
138    xdrproc_t xdr_argument, xdr_result;
139    char *(*local)(char *, struct svc_req *);
140
141    /*
142     * Don't bother authentication for NULLPROC.
143     */
144    if (rqstp->rq_proc == NULLPROC) {
145       (void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *)NULL);
146       return;
147    }
148
149    /*
150     * First get authentication.
151     */
152    switch (rqstp->rq_cred.oa_flavor) {
153       case AUTH_UNIX:
154          unix_cred = (struct authunix_parms *)rqstp->rq_clntcred;
155          break;
156       case AUTH_NULL:
157       default:
158          svcerr_weakauth(transp);
159          return;
160    }
161
162    switch (rqstp->rq_proc) {
163       case RQUOTAPROC_GETQUOTA:
164          xdr_argument = (xdrproc_t) xdr_ext_getquota_args;
165          xdr_result = (xdrproc_t) xdr_getquota_rslt;
166          local = (char *(*)(char *, struct svc_req *)) rquotaproc_getquota_2;
167          break;
168
169       case RQUOTAPROC_GETACTIVEQUOTA:
170          xdr_argument = (xdrproc_t) xdr_ext_getquota_args;
171          xdr_result = (xdrproc_t) xdr_getquota_rslt;
172          local = (char *(*)(char *, struct svc_req *)) rquotaproc_getactivequota_2;
173          break;
174
175       default:
176          svcerr_noproc(transp);
177          return;
178    }
179
180    (void) memset((char *)&argument, 0, sizeof (argument));
181    if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
182       svcerr_decode(transp);
183       return;
184    }
185    result = (*local)((char *)&argument, rqstp);
186    if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
187       svcerr_systemerr(transp);
188    }
189
190    if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
191       syslog(LOG_ERR, "unable to free arguments");
192       exit(1);
193    }
194    return;
195 }
196
197 int main(int argc, char **argv)
198 {
199    register SVCXPRT *transp;
200
201    (void) pmap_unset(RQUOTAPROG, RQUOTAVERS);
202    (void) pmap_unset(RQUOTAPROG, EXT_RQUOTAVERS);
203
204    openlog("rquota", LOG_PID, LOG_DAEMON);
205
206    transp = svcudp_create(RPC_ANYSOCK);
207    if (transp == NULL) {
208       syslog(LOG_ERR, "cannot create udp service.");
209       exit(1);
210    }
211    if (!svc_register(transp, RQUOTAPROG, RQUOTAVERS, rquotaprog_1, IPPROTO_UDP)) {
212       syslog(LOG_ERR, "unable to register (RQUOTAPROG, RQUOTAVERS, udp).");
213       exit(1);
214    }
215    if (!svc_register(transp, RQUOTAPROG, EXT_RQUOTAVERS, rquotaprog_2, IPPROTO_UDP)) {
216       syslog(LOG_ERR, "unable to register (RQUOTAPROG, EXT_RQUOTAVERS, udp).");
217       exit(1);
218    }
219
220    daemon(1,1);
221    svc_run();
222
223    syslog(LOG_ERR, "svc_run returned");
224    exit(1);
225    /* NOTREACHED */
226 }