audit: remove static local realms
[openafs.git] / src / tools / dumpscan / xf_rxcall.c
1 /*
2  * CMUCS AFStools
3  * dumpscan - routines for scanning and manipulating AFS volume dumps
4  *
5  * Copyright (c) 1998 Carnegie Mellon University
6  * All Rights Reserved.
7  *
8  * Permission to use, copy, modify and distribute this software and its
9  * documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie Mellon
26  * the rights to redistribute these changes.
27  */
28
29 /* xf_rxcall.c - XFILE routines for Rx bulk data transfers */
30
31 #include <sys/types.h>
32 #include <netinet/in.h>
33 #include <errno.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <fcntl.h>
37 #include <netdb.h>
38
39 #include "xfiles.h"
40 #include "xf_errs.h"
41
42 #include <rx/xdr.h>
43 #include <rx/rx.h>
44 #include <rx/rx_null.h>
45 #include <rx/rxkad.h>
46 #include <afs/auth.h>
47 #include <afs/cellconfig.h>
48 #include <afs/vlserver.h>
49 #include <afs/volser.h>
50 #include <afs/volint.h>
51
52 #ifndef AFSCONF_CLIENTNAME
53 #include <afs/dirpath.h>
54 #define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
55 #endif
56
57 #define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
58
59 struct rxinfo {
60     struct rx_connection *conn; /* connection */
61     struct rx_call *call;       /* call */
62     afs_int32 tid;              /* volser transaction ID */
63     afs_uint32 code;            /* result code */
64 };
65
66 static afs_uint32
67 xf_rxcall_do_read(XFILE * X, void *buf, afs_uint32 count)
68 {
69     struct rxinfo *i = X->refcon;
70     afs_uint32 xcount;
71
72     xcount = rx_Read(i->call, buf, count);
73     if (xcount == count)
74         return 0;
75     i->code = rx_EndCall(i->call, 0);
76     i->call = 0;
77     return i->code ? i->code : ERROR_XFILE_RDONLY;
78 }
79
80
81 static afs_uint32
82 xf_rxcall_do_write(XFILE * X, void *buf, afs_uint32 count)
83 {
84     struct rxinfo *i = X->refcon;
85     afs_uint32 xcount;
86
87     xcount = rx_Write(i->call, buf, count);
88     if (xcount == count)
89         return 0;
90     i->code = rx_EndCall(i->call, 0);
91     i->call = 0;
92     return i->code;
93 }
94
95
96 static afs_uint32
97 xf_rxcall_do_close(XFILE * X)
98 {
99     struct rxinfo *i = X->refcon;
100     afs_uint32 code;
101
102     if (i->call) {
103         code = rx_EndCall(i->call, i->code);
104         i->call = 0;
105     } else {
106         code = i->code;
107     }
108     free(i);
109     return code;
110 }
111
112
113 static afs_uint32
114 xf_voldump_do_close(XFILE * X)
115 {
116     struct rxinfo *i = X->refcon;
117     struct rx_connection *conn = i->conn;
118     afs_int32 code, rcode, xcode;
119     afs_int32 tid = i->tid;
120
121     code = xf_rxcall_do_close(X);
122     xcode = AFSVolEndTrans(conn, tid, &rcode);
123     if (!code)
124         code = xcode ? xcode : rcode;
125     return code;
126 }
127
128
129 afs_uint32
130 xfopen_rxcall(XFILE * X, int flag, struct rx_call * call)
131 {
132     struct rxinfo *i;
133
134     flag &= O_MODE_MASK;
135     if (flag == O_WRONLY)
136         return ERROR_XFILE_WRONLY;
137     memset(X, 0, sizeof(*X));
138     if (!(i = (struct rxinfo *)malloc(sizeof(struct rxinfo))))
139         return ENOMEM;
140     i->call = call;
141     i->code = 0;
142     X->do_read = xf_rxcall_do_read;
143     X->do_write = xf_rxcall_do_write;
144     X->do_close = xf_rxcall_do_close;
145     X->is_writable = (flag == O_RDWR);
146     X->refcon = i;
147     return 0;
148 }
149
150
151 afs_uint32
152 xfopen_voldump(XFILE * X, struct rx_connection * conn, afs_int32 part,
153                afs_int32 volid, afs_int32 date)
154 {
155     struct rx_call *call;
156     struct rxinfo *i;
157     afs_int32 code, rcode;
158     afs_int32 tid;
159
160     if ((code = AFSVolTransCreate(conn, volid, part, ITBusy, &tid)))
161         return code;
162     call = rx_NewCall(conn);
163     if ((code = StartAFSVolDump(call, tid, date))
164         || (code = xfopen_rxcall(X, O_RDONLY, call))) {
165         rx_EndCall(call, 0);
166         AFSVolEndTrans(conn, tid, &rcode);
167         return code;
168     }
169
170     i = X->refcon;
171     i->conn = conn;
172     i->tid = tid;
173     X->do_close = xf_voldump_do_close;
174     return 0;
175 }
176
177
178 afs_uint32
179 xfon_voldump(XFILE * X, int flag, char *name)
180 {
181     struct hostent *he;
182     struct rx_securityClass *class;
183     struct rx_connection *conn;
184     struct ktc_principal sname;
185     struct ktc_token token;
186     struct afsconf_dir *confdir;
187     afs_uint32 code, server_addr = 0;
188     afs_int32 volid, date, partid = 0;
189     int isnum, index;
190     char *x, *y;
191
192     /* Parse out the optional date and server location */
193     if ((code = rx_Init(0)))
194         return code;
195     if (!(name = strdup(name)))
196         return ENOMEM;
197     if ((x = strrchr(name, ','))) {
198         *x++ = 0;
199         date = atoi(x);
200     } else {
201         date = 0;
202     }
203     if ((x = strrchr(name, '@'))) {
204         int a, b, c, d;
205
206         *x++ = 0;
207         if (!(y = strchr(x, '/'))) {
208             free(name);
209             return VL_BADPARTITION;
210         }
211         *y++ = 0;
212         if (sscanf(x, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && a >= 0
213             && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0
214             && d <= 255) {
215             server_addr = (a << 24) | (b << 16) | (c << 8) | d;
216             server_addr = htonl(server_addr);
217         } else {
218             he = gethostbyname(x);
219             if (!he) {
220                 free(name);
221                 return VL_BADSERVER;
222             }
223             memcpy(&server_addr, he->h_addr, sizeof(server_addr));
224         }
225         partid = volutil_GetPartitionID(y);
226         if (partid < 0) {
227             free(name);
228             return VL_BADPARTITION;
229         }
230     }
231
232     /* Get tokens and set up a security object */
233     confdir = afsconf_Open(AFSCONF_CLIENTNAME);
234     if (!confdir) {
235         free(name);
236         return AFSCONF_NODB;
237     }
238     if ((code = afsconf_GetLocalCell(confdir, sname.cell, MAXKTCNAMELEN))) {
239         free(name);
240         return code;
241     }
242     afsconf_Close(confdir);
243     strcpy(sname.name, "afs");
244     sname.instance[0] = 0;
245     code = ktc_GetToken(&sname, &token, sizeof(token), 0);
246     if (code) {
247         class = rxnull_NewClientSecurityObject();
248         index = 0;
249     } else {
250         class =
251             rxkad_NewClientSecurityObject(rxkad_clear, &token.sessionKey,
252                                           token.kvno, token.ticketLen,
253                                           token.ticket);
254         index = 2;
255     }
256
257     /* Figure out the volume ID, looking it up in the VLDB if neccessary.
258      * Also look up the server and partition, if they were not specified.
259      */
260     for (isnum = 1, y = name; *y; y++)
261         if (*y < '0' || *y > '9')
262             isnum = 0;
263     if (isnum) {
264         volid = atoi(name);
265         if (!x) {
266             fprintf(stderr, "XXX: need to lookup volume by ID!\n");
267             exit(-1);
268         }
269     } else {
270         fprintf(stderr, "XXX: need to lookup volume by name!\n");
271         exit(-1);
272     }
273     free(name);
274
275     /* Establish a connection and start the call */
276     conn =
277         rx_NewConnection(server_addr, htons(AFSCONF_VOLUMEPORT),
278                          VOLSERVICE_ID, class, index);
279     return xfopen_voldump(X, conn, partid, volid, date);
280 }