2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
20 #include <sys/types.h>
23 #include <netinet/in.h>
24 #endif /* AFS_NT40_ENV */
27 #include <sys/statfs.h>
33 #include <rx/rx_globals.h>
35 #include <afs/vlserver.h>
37 #include <afs/cellconfig.h>
40 #include <afs/afsint.h>
47 struct ubik_client *cstruct;
48 static rxkad_level vsu_rxkad_level = rxkad_clear;
49 extern int VL_CreateEntry(), VL_CreateEntryN();
50 extern int VL_GetEntryByID(), VL_GetEntryByIDN();
51 extern int VL_GetEntryByNameO(), VL_GetEntryByNameN();
52 extern int VL_ReplaceEntry(), VL_ReplaceEntryN();
53 extern int VL_ListAttributes(), VL_ListAttributesN(), VL_ListAttributesN2();
55 static void ovlentry_to_nvlentry(oentryp, nentryp)
56 struct vldbentry *oentryp;
57 struct nvldbentry *nentryp;
61 memset(nentryp, 0, sizeof(struct nvldbentry));
62 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
63 for (i=0; i < oentryp->nServers; i++) {
64 nentryp->serverNumber[i] = oentryp->serverNumber[i];
65 nentryp->serverPartition[i] = oentryp->serverPartition[i];
66 nentryp->serverFlags[i] = oentryp->serverFlags[i];
68 nentryp->nServers = oentryp->nServers;
69 for (i=0; i<MAXTYPES; i++)
70 nentryp->volumeId[i] = oentryp->volumeId[i];
71 nentryp->cloneId = oentryp->cloneId;
72 nentryp->flags = oentryp->flags;
75 static nvlentry_to_ovlentry(nentryp, oentryp)
76 struct nvldbentry *nentryp;
77 struct vldbentry *oentryp;
81 memset(oentryp, 0, sizeof(struct vldbentry));
82 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
83 if (nentryp->nServers > OMAXNSERVERS) {
85 * The alternative is to store OMAXSERVERS but it's always better
86 * to know what's going on...
90 for (i=0; i < nentryp->nServers; i++) {
91 oentryp->serverNumber[i] = nentryp->serverNumber[i];
92 oentryp->serverPartition[i] = nentryp->serverPartition[i];
93 oentryp->serverFlags[i] = nentryp->serverFlags[i];
95 oentryp->nServers = i;
96 for (i=0; i<MAXTYPES; i++)
97 oentryp->volumeId[i] = nentryp->volumeId[i];
98 oentryp->cloneId = nentryp->cloneId;
99 oentryp->flags = nentryp->flags;
103 static int newvlserver=0;
105 VLDB_CreateEntry(entryp)
106 struct nvldbentry *entryp;
108 struct vldbentry oentry;
111 if (newvlserver == 1) {
113 code = nvlentry_to_ovlentry(entryp, &oentry);
116 code = ubik_Call(VL_CreateEntry, cstruct, 0, &oentry);
119 code = ubik_Call(VL_CreateEntryN, cstruct, 0, entryp);
121 if (code == RXGEN_OPCODE) {
122 newvlserver = 1; /* Doesn't support new interface */
131 VLDB_GetEntryByID(volid, voltype, entryp)
132 afs_int32 volid, voltype;
133 struct nvldbentry *entryp;
135 struct vldbentry oentry;
138 if (newvlserver == 1) {
140 code = ubik_Call(VL_GetEntryByID, cstruct, 0, volid, voltype, &oentry);
142 ovlentry_to_nvlentry(&oentry, entryp);
145 code = ubik_Call(VL_GetEntryByIDN, cstruct, 0, volid, voltype, entryp);
147 if (code == RXGEN_OPCODE) {
148 newvlserver = 1; /* Doesn't support new interface */
157 VLDB_GetEntryByName(namep, entryp)
159 struct nvldbentry *entryp;
161 struct vldbentry oentry;
164 if (newvlserver == 1) {
166 code = ubik_Call(VL_GetEntryByNameO, cstruct, 0, namep, &oentry);
168 ovlentry_to_nvlentry(&oentry, entryp);
171 code = ubik_Call(VL_GetEntryByNameN, cstruct, 0, namep, entryp);
173 if (code == RXGEN_OPCODE) {
174 newvlserver = 1; /* Doesn't support new interface */
183 VLDB_ReplaceEntry(volid, voltype, entryp, releasetype)
184 afs_int32 volid, voltype, releasetype;
185 struct nvldbentry *entryp;
187 struct vldbentry oentry;
190 if (newvlserver == 1) {
192 code = nvlentry_to_ovlentry(entryp, &oentry);
195 code = ubik_Call(VL_ReplaceEntry, cstruct, 0, volid, voltype, &oentry, releasetype);
198 code = ubik_Call(VL_ReplaceEntryN, cstruct, 0, volid, voltype, entryp, releasetype);
200 if (code == RXGEN_OPCODE) {
201 newvlserver = 1; /* Doesn't support new interface */
212 VLDB_ListAttributes(attrp, entriesp, blkentriesp)
213 VldbListByAttributes *attrp;
215 nbulkentries *blkentriesp;
217 bulkentries arrayEntries;
218 register int code, i;
220 if (newvlserver == 1) {
222 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
223 code = ubik_Call(VL_ListAttributes, cstruct, 0, attrp, entriesp, &arrayEntries);
225 blkentriesp->nbulkentries_val = (nvldbentry *)malloc(*entriesp * sizeof(struct nvldbentry));
226 for (i = 0; i < *entriesp; i++) { /* process each entry */
227 ovlentry_to_nvlentry(&arrayEntries.bulkentries_val[i], &blkentriesp->nbulkentries_val[i]);
230 if (arrayEntries.bulkentries_val) free(arrayEntries.bulkentries_val);
233 code = ubik_Call(VL_ListAttributesN, cstruct, 0, attrp, entriesp, blkentriesp);
235 if (code == RXGEN_OPCODE) {
236 newvlserver = 1; /* Doesn't support new interface */
245 VLDB_ListAttributesN2(attrp, name, thisindex, nentriesp, blkentriesp, nextindexp)
246 VldbListByAttributes *attrp;
249 afs_int32 *nentriesp;
250 nbulkentries *blkentriesp;
251 afs_int32 *nextindexp;
255 code = ubik_Call(VL_ListAttributesN2, cstruct, 0,
256 attrp, (name?name:""), thisindex,
257 nentriesp, blkentriesp, nextindexp);
262 static int vlserverv4=-1;
266 afs_uint32 addrs[16];
268 struct cacheips cacheips[16];
270 extern int VL_GetAddrsU();
271 VLDB_IsSameAddrs(serv1, serv2, errorp)
272 afs_int32 serv1, serv2, *errorp;
275 ListAddrByAttributes attrs;
277 afs_uint32 *addrp, nentries, unique, i, j, f1, f2;
279 static int initcache = 0;
285 if (vlserverv4 == 1) {
289 for (i=0; i<16; i++) {
290 cacheips[i].server = cacheips[i].count = 0;
295 /* See if it's cached */
296 for (i=0; i<16; i++) {
298 for (j=0; j < cacheips[i].count; j++) {
299 if (serv1 == cacheips[i].addrs[j]) f1 = 1;
300 else if (serv2 == cacheips[i].addrs[j]) f2 = 1;
309 memset(&attrs, 0, sizeof(attrs));
310 attrs.Mask = VLADDR_IPADDR;
311 attrs.ipaddr = serv1;
312 memset(&addrs, 0, sizeof(addrs));
313 memset(&uuid, 0, sizeof(uuid));
314 code = ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid, &unique, &nentries, &addrs);
315 if (vlserverv4 == -1) {
316 if (code == RXGEN_OPCODE) {
317 vlserverv4 = 1; /* Doesn't support new interface */
323 if (code == VL_NOENT)
331 if (++cacheip_index >= 16) cacheip_index = 0;
332 cacheips[cacheip_index].server = serv1;
333 cacheips[cacheip_index].count = nentries;
334 addrp = addrs.bulkaddrs_val;
335 for (i=0; i<nentries; i++, addrp++) {
336 cacheips[cacheip_index].addrs[i] = *addrp;
337 if (serv2 == *addrp) {
346 afs_int32 subik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)
347 register struct ubik_client *aclient;
350 afs_int32 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16;
352 struct vldbentry vldbentry;
353 register int code, (*nproc)();
355 if (newvlserver == 1) {
357 code = ubik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16);
359 if (code == RXGEN_OPCODE) {
360 newvlserver = 1; /* Doesn't support new interface */
370 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
371 for authenticated connections; if zero, encryption is turned off.
372 Calling this function always results in a level of at least rxkad_auth;
373 to get a rxkad_clear connection, simply don't call this.
375 void vsu_SetCrypt(cryptflag)
379 vsu_rxkad_level = rxkad_crypt;
381 vsu_rxkad_level = rxkad_auth;
387 Get the appropriate type of ubik client structure out from the system.
389 afs_int32 vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc)
393 struct ubik_client **uclientp;
397 afs_int32 code, scIndex, i;
398 struct afsconf_cell info;
399 struct afsconf_dir *tdir;
400 struct ktc_principal sname;
401 struct ktc_token ttoken;
402 struct rx_securityClass *sc;
403 static struct rx_connection *serverconns[VLDB_MAXSERVERS];
409 fprintf(STDERR,"vsu_ClientInit: could not initialize rx.\n");
412 rx_SetRxDeadTime(90);
414 if (sauth) { /* -localauth */
415 tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
417 fprintf(STDERR, "vsu_ClientInit: Could not process files in configuration directory (%s).\n",
418 AFSDIR_SERVER_ETC_DIRPATH);
421 code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */
423 fprintf(STDERR, "vsu_ClientInit: Could not get security object for -localAuth\n");
426 code = afsconf_GetCellInfo(tdir, tdir->cellName, AFSCONF_VLDBSERVICE,
429 fprintf(STDERR, "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n",
430 cellName, AFSDIR_SERVER_ETC_DIRPATH,AFSDIR_CELLSERVDB_FILE);
434 else { /* not -localauth */
435 tdir = afsconf_Open(confDir);
437 fprintf(STDERR, "vsu_ClientInit: Could not process files in configuration directory (%s).\n",
443 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
445 fprintf(STDERR, "vsu_ClientInit: can't get local cellname, check %s/%s\n",
446 confDir, AFSDIR_THISCELL_FILE);
452 code = afsconf_GetCellInfo(tdir, cellName, AFSCONF_VLDBSERVICE, &info);
454 fprintf(STDERR, "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n",
455 cellName, confDir,AFSDIR_CELLSERVDB_FILE);
458 if (noAuthFlag) /* -noauth */
460 else { /* not -noauth */
461 strcpy(sname.cell, info.name);
462 sname.instance[0] = 0;
463 strcpy(sname.name, "afs");
464 code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), (char *)0);
465 if (code) { /* did not get ticket */
466 fprintf(STDERR, "vsu_ClientInit: Could not get afs tokens, running unauthenticated.\n");
469 else { /* got a ticket */
471 if ((ttoken.kvno < 0) || (ttoken.kvno > 255)) {
472 fprintf(STDERR, "vsu_ClientInit: funny kvno (%d) in ticket, proceeding\n",
480 sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
483 sc = (struct rx_securityClass *)rxkad_NewClientSecurityObject(
484 vsu_rxkad_level, &ttoken.sessionKey, ttoken.kvno,
485 ttoken.ticketLen, ttoken.ticket);
488 fprintf(STDERR, "vsu_ClientInit: unsupported security index %d\n",
495 if (secproc) /* tell UV module about default authentication */
496 (*secproc) (sc, scIndex);
497 if (info.numServers > VLDB_MAXSERVERS) {
498 fprintf(STDERR, "vsu_ClientInit: info.numServers=%d (> VLDB_MAXSERVERS=%d)\n",
499 info.numServers, VLDB_MAXSERVERS);
502 for (i=0; i<info.numServers; i++) {
503 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
504 info.hostAddr[i].sin_port, USER_SERVICE_ID,
508 code = ubik_ClientInit(serverconns, uclientp);
510 fprintf(STDERR, "vsu_ClientInit: ubik client init failed.\n");
517 /*extract the name of volume <name> without readonly or backup suffixes
518 * and return the result as <rname>.
520 vsu_ExtractName(rname,name)
526 total = strlen(sname);
527 if(!strcmp(&sname[total - 9],".readonly")) {
528 /*discard the last 8 chars */
529 sname[total - 9] = '\0';
533 else if(!strcmp(&sname[total - 7 ],".backup")) {
534 /*discard last 6 chars */
535 sname[total - 7] = '\0';
540 strncpy(rname,name,VOLSER_OLDMAXVOLNAME);
546 /* returns 0 if failed */
547 afs_uint32 vsu_GetVolumeID(astring, acstruct, errp)
548 struct ubik_client *acstruct;
551 afs_uint32 tc, value;
553 char *str,*ptr, volname[VOLSER_OLDMAXVOLNAME+1];
555 struct nvldbentry entry;
560 total = strlen(astring);
564 while (curval = *str++){
565 if(curval < '0' || curval > '9')
570 vsu_ExtractName(volname,astring);
571 vcode = VLDB_GetEntryByName(volname, &entry);
573 if(!strcmp(&astring[total - 9],".readonly"))
574 return entry.volumeId[ROVOL];
575 else if ((!strcmp(&astring[total - 7 ],".backup")))
576 return entry.volumeId[BACKVOL];
578 return (entry.volumeId[RWVOL]);
581 return 0; /* can't find volume */
586 while (tc = *astring++) {
588 if(!tryname) fprintf(STDERR,"goofed in volid \n");
589 else {fprintf(STDERR,"Could not get entry from vldb for %s\n",ptr);PrintError("",vcode);}
593 if (tc < '0' || tc > '9'){
594 if(!tryname) fprintf(STDERR,"internal error: out of range char in vol ID\n");
595 else {fprintf(STDERR,"Could not get entry from vldb for %s\n",ptr);PrintError("",vcode);}