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>
42 #include <rx/rx_globals.h>
44 #include <afs/vlserver.h>
46 #include <afs/cellconfig.h>
49 #include <afs/afsint.h>
56 struct ubik_client *cstruct;
57 static rxkad_level vsu_rxkad_level = rxkad_clear;
58 extern int VL_CreateEntry(), VL_CreateEntryN();
59 extern int VL_GetEntryByID(), VL_GetEntryByIDN();
60 extern int VL_GetEntryByNameO(), VL_GetEntryByNameN();
61 extern int VL_ReplaceEntry(), VL_ReplaceEntryN();
62 extern int VL_ListAttributes(), VL_ListAttributesN(), VL_ListAttributesN2();
64 static void ovlentry_to_nvlentry(oentryp, nentryp)
65 struct vldbentry *oentryp;
66 struct nvldbentry *nentryp;
70 memset(nentryp, 0, sizeof(struct nvldbentry));
71 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
72 for (i=0; i < oentryp->nServers; i++) {
73 nentryp->serverNumber[i] = oentryp->serverNumber[i];
74 nentryp->serverPartition[i] = oentryp->serverPartition[i];
75 nentryp->serverFlags[i] = oentryp->serverFlags[i];
77 nentryp->nServers = oentryp->nServers;
78 for (i=0; i<MAXTYPES; i++)
79 nentryp->volumeId[i] = oentryp->volumeId[i];
80 nentryp->cloneId = oentryp->cloneId;
81 nentryp->flags = oentryp->flags;
84 static nvlentry_to_ovlentry(nentryp, oentryp)
85 struct nvldbentry *nentryp;
86 struct vldbentry *oentryp;
90 memset(oentryp, 0, sizeof(struct vldbentry));
91 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
92 if (nentryp->nServers > OMAXNSERVERS) {
94 * The alternative is to store OMAXSERVERS but it's always better
95 * to know what's going on...
99 for (i=0; i < nentryp->nServers; i++) {
100 oentryp->serverNumber[i] = nentryp->serverNumber[i];
101 oentryp->serverPartition[i] = nentryp->serverPartition[i];
102 oentryp->serverFlags[i] = nentryp->serverFlags[i];
104 oentryp->nServers = i;
105 for (i=0; i<MAXTYPES; i++)
106 oentryp->volumeId[i] = nentryp->volumeId[i];
107 oentryp->cloneId = nentryp->cloneId;
108 oentryp->flags = nentryp->flags;
112 static int newvlserver=0;
114 VLDB_CreateEntry(entryp)
115 struct nvldbentry *entryp;
117 struct vldbentry oentry;
120 if (newvlserver == 1) {
122 code = nvlentry_to_ovlentry(entryp, &oentry);
125 code = ubik_Call(VL_CreateEntry, cstruct, 0, &oentry);
128 code = ubik_Call(VL_CreateEntryN, cstruct, 0, entryp);
130 if (code == RXGEN_OPCODE) {
131 newvlserver = 1; /* Doesn't support new interface */
140 VLDB_GetEntryByID(volid, voltype, entryp)
141 afs_int32 volid, voltype;
142 struct nvldbentry *entryp;
144 struct vldbentry oentry;
147 if (newvlserver == 1) {
149 code = ubik_Call(VL_GetEntryByID, cstruct, 0, volid, voltype, &oentry);
151 ovlentry_to_nvlentry(&oentry, entryp);
154 code = ubik_Call(VL_GetEntryByIDN, cstruct, 0, volid, voltype, entryp);
156 if (code == RXGEN_OPCODE) {
157 newvlserver = 1; /* Doesn't support new interface */
166 VLDB_GetEntryByName(namep, entryp)
168 struct nvldbentry *entryp;
170 struct vldbentry oentry;
173 if (newvlserver == 1) {
175 code = ubik_Call(VL_GetEntryByNameO, cstruct, 0, namep, &oentry);
177 ovlentry_to_nvlentry(&oentry, entryp);
180 code = ubik_Call(VL_GetEntryByNameN, cstruct, 0, namep, entryp);
182 if (code == RXGEN_OPCODE) {
183 newvlserver = 1; /* Doesn't support new interface */
192 VLDB_ReplaceEntry(volid, voltype, entryp, releasetype)
193 afs_int32 volid, voltype, releasetype;
194 struct nvldbentry *entryp;
196 struct vldbentry oentry;
199 if (newvlserver == 1) {
201 code = nvlentry_to_ovlentry(entryp, &oentry);
204 code = ubik_Call(VL_ReplaceEntry, cstruct, 0, volid, voltype, &oentry, releasetype);
207 code = ubik_Call(VL_ReplaceEntryN, cstruct, 0, volid, voltype, entryp, releasetype);
209 if (code == RXGEN_OPCODE) {
210 newvlserver = 1; /* Doesn't support new interface */
221 VLDB_ListAttributes(attrp, entriesp, blkentriesp)
222 VldbListByAttributes *attrp;
224 nbulkentries *blkentriesp;
226 bulkentries arrayEntries;
227 register int code, i;
229 if (newvlserver == 1) {
231 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
232 code = ubik_Call(VL_ListAttributes, cstruct, 0, attrp, entriesp, &arrayEntries);
234 blkentriesp->nbulkentries_val = (nvldbentry *)malloc(*entriesp * sizeof(struct nvldbentry));
235 for (i = 0; i < *entriesp; i++) { /* process each entry */
236 ovlentry_to_nvlentry(&arrayEntries.bulkentries_val[i], &blkentriesp->nbulkentries_val[i]);
239 if (arrayEntries.bulkentries_val) free(arrayEntries.bulkentries_val);
242 code = ubik_Call(VL_ListAttributesN, cstruct, 0, attrp, entriesp, blkentriesp);
244 if (code == RXGEN_OPCODE) {
245 newvlserver = 1; /* Doesn't support new interface */
254 VLDB_ListAttributesN2(attrp, name, thisindex, nentriesp, blkentriesp, nextindexp)
255 VldbListByAttributes *attrp;
258 afs_int32 *nentriesp;
259 nbulkentries *blkentriesp;
260 afs_int32 *nextindexp;
264 code = ubik_Call(VL_ListAttributesN2, cstruct, 0,
265 attrp, (name?name:""), thisindex,
266 nentriesp, blkentriesp, nextindexp);
271 static int vlserverv4=-1;
275 afs_uint32 addrs[16];
278 * Increase cache size. This avoids high CPU usage by the vlserver
279 * in environments where there are more than 16 fileservers in the
282 #define GETADDRUCACHESIZE 64
283 struct cacheips cacheips[GETADDRUCACHESIZE];
285 extern int VL_GetAddrsU();
286 VLDB_IsSameAddrs(serv1, serv2, errorp)
287 afs_int32 serv1, serv2, *errorp;
290 ListAddrByAttributes attrs;
292 afs_uint32 *addrp, nentries, unique, i, j, f1, f2;
294 static int initcache = 0;
300 if (vlserverv4 == 1) {
304 for (i=0; i < GETADDRUCACHESIZE; i++) {
305 cacheips[i].server = cacheips[i].count = 0;
310 /* See if it's cached */
311 for (i=0; i < GETADDRUCACHESIZE; i++) {
313 for (j=0; j < cacheips[i].count; j++) {
314 if (serv1 == cacheips[i].addrs[j]) f1 = 1;
315 else if (serv2 == cacheips[i].addrs[j]) f2 = 1;
322 if (cacheips[i].server == serv1)
326 memset(&attrs, 0, sizeof(attrs));
327 attrs.Mask = VLADDR_IPADDR;
328 attrs.ipaddr = serv1;
329 memset(&addrs, 0, sizeof(addrs));
330 memset(&uuid, 0, sizeof(uuid));
331 code = ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid, &unique, &nentries, &addrs);
332 if (vlserverv4 == -1) {
333 if (code == RXGEN_OPCODE) {
334 vlserverv4 = 1; /* Doesn't support new interface */
340 if (code == VL_NOENT)
348 if (nentries > GETADDRUCACHESIZE) nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
349 if (++cacheip_index >= GETADDRUCACHESIZE) cacheip_index = 0;
350 cacheips[cacheip_index].server = serv1;
351 cacheips[cacheip_index].count = nentries;
352 addrp = addrs.bulkaddrs_val;
353 for (i=0; i<nentries; i++, addrp++) {
354 cacheips[cacheip_index].addrs[i] = *addrp;
355 if (serv2 == *addrp) {
364 afs_int32 subik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)
365 register struct ubik_client *aclient;
368 afs_int32 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16;
370 struct vldbentry vldbentry;
371 register int code, (*nproc)();
373 if (newvlserver == 1) {
375 code = ubik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16);
377 if (code == RXGEN_OPCODE) {
378 newvlserver = 1; /* Doesn't support new interface */
388 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
389 for authenticated connections; if zero, encryption is turned off.
390 Calling this function always results in a level of at least rxkad_auth;
391 to get a rxkad_clear connection, simply don't call this.
393 void vsu_SetCrypt(cryptflag)
397 vsu_rxkad_level = rxkad_crypt;
399 vsu_rxkad_level = rxkad_auth;
405 Get the appropriate type of ubik client structure out from the system.
407 afs_int32 vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc)
411 struct ubik_client **uclientp;
415 afs_int32 code, scIndex, i;
416 struct afsconf_cell info;
417 struct afsconf_dir *tdir;
418 struct ktc_principal sname;
419 struct ktc_token ttoken;
420 struct rx_securityClass *sc;
421 static struct rx_connection *serverconns[VLDB_MAXSERVERS];
427 fprintf(STDERR,"vsu_ClientInit: could not initialize rx.\n");
430 rx_SetRxDeadTime(90);
432 if (sauth) { /* -localauth */
433 tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
435 fprintf(STDERR, "vsu_ClientInit: Could not process files in configuration directory (%s).\n",
436 AFSDIR_SERVER_ETC_DIRPATH);
439 code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */
441 fprintf(STDERR, "vsu_ClientInit: Could not get security object for -localAuth\n");
444 code = afsconf_GetCellInfo(tdir, tdir->cellName, AFSCONF_VLDBSERVICE,
447 fprintf(STDERR, "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n",
448 cellName, AFSDIR_SERVER_ETC_DIRPATH,AFSDIR_CELLSERVDB_FILE);
452 else { /* not -localauth */
453 tdir = afsconf_Open(confDir);
455 fprintf(STDERR, "vsu_ClientInit: Could not process files in configuration directory (%s).\n",
461 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
463 fprintf(STDERR, "vsu_ClientInit: can't get local cellname, check %s/%s\n",
464 confDir, AFSDIR_THISCELL_FILE);
470 code = afsconf_GetCellInfo(tdir, cellName, AFSCONF_VLDBSERVICE, &info);
472 fprintf(STDERR, "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n",
473 cellName, confDir,AFSDIR_CELLSERVDB_FILE);
476 if (noAuthFlag) /* -noauth */
478 else { /* not -noauth */
479 strcpy(sname.cell, info.name);
480 sname.instance[0] = 0;
481 strcpy(sname.name, "afs");
482 code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
483 if (code) { /* did not get ticket */
484 fprintf(STDERR, "vsu_ClientInit: Could not get afs tokens, running unauthenticated.\n");
487 else { /* got a ticket */
489 if ((ttoken.kvno < 0) || (ttoken.kvno > 255)) {
490 fprintf(STDERR, "vsu_ClientInit: funny kvno (%d) in ticket, proceeding\n",
498 sc = rxnull_NewClientSecurityObject();
501 sc = rxkad_NewClientSecurityObject(
502 vsu_rxkad_level, &ttoken.sessionKey, ttoken.kvno,
503 ttoken.ticketLen, ttoken.ticket);
506 fprintf(STDERR, "vsu_ClientInit: unsupported security index %d\n",
515 if (secproc) /* tell UV module about default authentication */
516 (*secproc) (sc, scIndex);
517 if (info.numServers > VLDB_MAXSERVERS) {
518 fprintf(STDERR, "vsu_ClientInit: info.numServers=%d (> VLDB_MAXSERVERS=%d)\n",
519 info.numServers, VLDB_MAXSERVERS);
522 for (i=0; i<info.numServers; i++) {
523 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
524 info.hostAddr[i].sin_port, USER_SERVICE_ID,
528 code = ubik_ClientInit(serverconns, uclientp);
530 fprintf(STDERR, "vsu_ClientInit: ubik client init failed.\n");
537 /*extract the name of volume <name> without readonly or backup suffixes
538 * and return the result as <rname>.
540 vsu_ExtractName(rname,name)
542 { char sname[VOLSER_OLDMAXVOLNAME+1];
545 strncpy(sname, name, sizeof(sname));
546 sname[sizeof(sname)-1] = '\0';
547 total = strlen(sname);
548 if(!strcmp(&sname[total - 9],".readonly")) {
549 /*discard the last 8 chars */
550 sname[total - 9] = '\0';
551 strcpy(rname, sname);
554 else if(!strcmp(&sname[total - 7],".backup")) {
555 /*discard last 6 chars */
556 sname[total - 7] = '\0';
561 strncpy(rname,name,VOLSER_OLDMAXVOLNAME);
562 rname[VOLSER_OLDMAXVOLNAME] = '\0';
568 /* returns 0 if failed */
569 afs_uint32 vsu_GetVolumeID(astring, acstruct, errp)
570 struct ubik_client *acstruct;
573 afs_uint32 tc, value;
575 char *str,*ptr, volname[VOLSER_OLDMAXVOLNAME+1];
577 struct nvldbentry entry;
582 total = strlen(astring);
586 while ((curval = *str++)){
587 if(curval < '0' || curval > '9')
592 vsu_ExtractName(volname,astring);
593 vcode = VLDB_GetEntryByName(volname, &entry);
595 if(!strcmp(&astring[total - 9],".readonly"))
596 return entry.volumeId[ROVOL];
597 else if ((!strcmp(&astring[total - 7 ],".backup")))
598 return entry.volumeId[BACKVOL];
600 return (entry.volumeId[RWVOL]);
603 return 0; /* can't find volume */
608 while ((tc = *astring++)) {
610 if(!tryname) fprintf(STDERR,"goofed in volid \n");
611 else {fprintf(STDERR,"Could not get entry from vldb for %s\n",ptr);PrintError("",vcode);}
615 if (tc < '0' || tc > '9'){
616 if(!tryname) fprintf(STDERR,"internal error: out of range char in vol ID\n");
617 else {fprintf(STDERR,"Could not get entry from vldb for %s\n",ptr);PrintError("",vcode);}