void InitErrTabs(void) { #ifndef AFS_PTHREAD_ENV initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_VOLS_error_table(); #endif return; }
/* * Initialize all the error tables that may be used by com_err * in this module. */ void InitErrTabs(void) { initialize_ACFG_error_table(); initialize_KA_error_table(); initialize_RXK_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_BUTM_error_table(); initialize_VOLS_error_table(); initialize_BUTC_error_table(); initialize_BUTX_error_table(); initialize_BUDB_error_table(); initialize_BUCD_error_table(); initialize_KTC_error_table(); }
int main(int argc, char *argv[]) { int i; afs_int32 code; afs_int32 offset; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ struct sigaction nsa; sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGSEGV, &nsa, NULL); #endif initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_PT_error_table(); initialize_BZ_error_table(); initialize_U_error_table(); initialize_VOLS_error_table(); if (argc < 2) { fprintf(stderr, "Usage is: %s [<code>]+\n", argv[0]); exit(1); } for (i = 1; i < argc; i++) { code = atoi(argv[i]); offset = code & ((1 << ERRCODE_RANGE) - 1); printf("%d (%s).%d = %s\n", (int)code, afs_error_table_name(code), (int)offset, afs_error_message(code)); } return 0; }
afs_int32 ka_Init(int flags) { /* reserved for future use. */ afs_int32 code; static int inited = 0; LOCK_GLOBAL_MUTEX; if (inited) { UNLOCK_GLOBAL_MUTEX; return 0; } inited++; initialize_U_error_table(); initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH); UNLOCK_GLOBAL_MUTEX; if (code) return code; return 0; }
afs_int32 pr_Initialize(IN afs_int32 secLevel, IN const char *confDir, IN char *cell) { afs_int32 code; struct rx_connection *serverconns[MAXSERVERS]; struct rx_securityClass *sc = NULL; static struct afsconf_dir *tdir = (struct afsconf_dir *)NULL; /* only do this once */ static char tconfDir[100] = ""; static char tcell[64] = ""; afs_int32 scIndex; afs_int32 secFlags; static struct afsconf_cell info; afs_int32 i; #if !defined(UKERNEL) char cellstr[64]; #endif afs_int32 gottdir = 0; afs_int32 refresh = 0; initialize_PT_error_table(); initialize_RXK_error_table(); initialize_ACFG_error_table(); initialize_KTC_error_table(); #if defined(UKERNEL) if (!cell) { cell = afs_LclCellName; } #else /* defined(UKERNEL) */ if (!cell) { if (!tdir) tdir = afsconf_Open(confDir); if (!tdir) { if (confDir && strcmp(confDir, "")) fprintf(stderr, "%s: Could not open configuration directory: %s.\n", whoami, confDir); else fprintf(stderr, "%s: No configuration directory specified.\n", whoami); return -1; } gottdir = 1; code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr)); if (code) { fprintf(stderr, "libprot: Could not get local cell. [%d]\n", code); return code; } cell = cellstr; } #endif /* defined(UKERNEL) */ if (tdir == NULL || strcmp(confDir, tconfDir) || strcmp(cell, tcell)) { /* * force re-evaluation. we either don't have an afsconf_dir, * the directory has changed or the cell has changed. */ if (tdir && !gottdir) { afsconf_Close(tdir); tdir = (struct afsconf_dir *)NULL; } pruclient = (struct ubik_client *)NULL; refresh = 1; } if (refresh) { strncpy(tconfDir, confDir, sizeof(tconfDir)); strncpy(tcell, cell, sizeof(tcell)); #if defined(UKERNEL) tdir = afs_cdir; #else /* defined(UKERNEL) */ if (!gottdir) tdir = afsconf_Open(confDir); if (!tdir) { if (confDir && strcmp(confDir, "")) fprintf(stderr, "libprot: Could not open configuration directory: %s.\n", confDir); else fprintf(stderr, "libprot: No configuration directory specified.\n"); return -1; } #endif /* defined(UKERNEL) */ code = afsconf_GetCellInfo(tdir, cell, "afsprot", &info); if (code) { fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n", cell, confDir, AFSDIR_CELLSERVDB_FILE); return code; } } /* If we already have a client and it is at the security level we * want, don't get a new one. Unless the security level is 2 in * which case we will get one (and re-read the key file). */ if (pruclient && (lastLevel == secLevel) && (secLevel != 2)) { return 0; } code = rx_Init(0); if (code) { fprintf(stderr, "libprot: Could not initialize rx.\n"); return code; } /* Most callers use secLevel==1, however, the fileserver uses secLevel==2 * to force use of the KeyFile. secLevel == 0 implies -noauth was * specified. */ if (secLevel == 2) { code = afsconf_GetLatestKey(tdir, 0, 0); if (code) { afs_com_err(whoami, code, "(getting key from local KeyFile)\n"); } else { /* If secLevel is two assume we're on a file server and use * ClientAuthSecure if possible. */ code = afsconf_ClientAuthSecure(tdir, &sc, &scIndex); if (code) afs_com_err(whoami, code, "(calling client secure)\n"); } } else if (secLevel > 0) { secFlags = 0; if (secLevel > 1) secFlags |= AFSCONF_SECOPTS_ALWAYSENCRYPT; code = afsconf_ClientAuthToken(&info, secFlags, &sc, &scIndex, NULL); if (code) { afs_com_err(whoami, code, "(getting token)"); if (secLevel > 1) return code; } } if (sc == NULL) { sc = rxnull_NewClientSecurityObject(); scIndex = RX_SECIDX_NULL; } if ((scIndex == RX_SECIDX_NULL) && (secLevel != 0)) fprintf(stderr, "%s: Could not get afs tokens, running unauthenticated\n", whoami); memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */ for (i = 0; i < info.numServers; i++) serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port, PRSRV, sc, scIndex); code = ubik_ClientInit(serverconns, &pruclient); if (code) { afs_com_err(whoami, code, "ubik client init failed."); return code; } lastLevel = scIndex; code = rxs_Release(sc); return code; }
static int WorkerBee(struct cmd_syndesc *as, void *arock) { afs_int32 code; struct rx_securityClass *(securityObjects[3]); struct rx_service *service; time_t tokenExpires; char cellName[64]; int localauth; /*process arguments */ afs_int32 portOffset = 0; #ifdef AFS_PTHREAD_ENV pthread_t dbWatcherPid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS dbWatcherPid; #endif afs_uint32 host = htonl(INADDR_ANY); debugLevel = 0; /*initialize the error tables */ initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_BUTM_error_table(); initialize_BUTC_error_table(); #ifdef xbsa initialize_BUTX_error_table(); #endif /*xbs */ initialize_VOLS_error_table(); initialize_BUDB_error_table(); initialize_BUCD_error_table(); if (as->parms[0].items) { portOffset = SafeATOL(as->parms[0].items->data); if (portOffset == -1) { fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data); exit(1); } else if (portOffset > BC_MAXPORTOFFSET) { fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET); exit(1); } } xbsaType = XBSA_SERVER_TYPE_NONE; /* default */ if (as->parms[3].items) { /* -device */ globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */ globalTapeConfig.fileMarkSize = 0; globalTapeConfig.portOffset = portOffset; strncpy(globalTapeConfig.device, as->parms[3].items->data, 100); xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */ } else { /* Search for an entry in tapeconfig file */ code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset); if (code == -1) { fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile); exit(1); } /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so * it's an XBSA server. Don't know if its ADSM or not so its unknown. */ xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE); } if (as->parms[6].items) { /* -restoretofile */ int s = strlen(as->parms[6].items->data); restoretofile = malloc(s + 1); strncpy(restoretofile, as->parms[6].items->data, s + 1); printf("Restore to file '%s'\n", restoretofile); } /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set * the exact xbsaType within the call (won't be unknown) - double check. */ code = GetConfigParams(pFile, portOffset); if (code) exit(code); #ifdef xbsa if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) { printf ("\nConfiguration file error, the TYPE parameter must be specified, or\n"); printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset); exit(1); } #else /* Not compiled for XBSA code so we can't support it */ if (CONF_XBSA) { printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset); printf("This binary does not have XBSA support\n"); exit(1); } #endif /* Open the log files. The pathnames were set in GetConfigParams() */ logIO = fopen(logFile, "a"); if (!logIO) { fprintf(stderr, "Failed to open %s\n", logFile); exit(1); } ErrorlogIO = fopen(ErrorlogFile, "a"); if (!ErrorlogIO) { fprintf(stderr, "Failed to open %s\n", ErrorlogFile); exit(1); } if (lastLog) { lastLogIO = fopen(lastLogFile, "a"); if (!lastLogIO) { fprintf(stderr, "Failed to open %s\n", lastLogFile); exit(1); } } if (centralLogFile) { struct stat sbuf; afs_int32 statcode; #ifndef AFS_NT40_ENV char path[AFSDIR_PATH_MAX]; #endif statcode = stat(centralLogFile, &sbuf); centralLogIO = fopen(centralLogFile, "a"); if (!centralLogIO) { fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile, errno); exit(1); } #ifndef AFS_NT40_ENV /* Make sure it is not in AFS, has to have been created first */ if (!realpath(centralLogFile, path)) { fprintf(stderr, "Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno); } else { if (strncmp(path, "/afs/", 5) == 0) { fprintf(stderr, "The central log '%s' should not be in AFS\n", centralLogFile); exit(1); } } #endif /* Write header if created it */ if (statcode) { char *h1 = "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n"; char *h2 = "----- ------------------- ------------------- -------- ---------\n"; /* File didn't exist before so write the header lines */ fwrite(h1, strlen(h1), 1, centralLogIO); fwrite(h2, strlen(h2), 1, centralLogIO); fflush(centralLogIO); } } if (as->parms[1].items) { debugLevel = SafeATOL(as->parms[1].items->data); if (debugLevel == -1) { TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data); exit(1); } } #ifdef xbsa /* Setup XBSA library interface */ if (CONF_XBSA) { afs_int32 rc; rc = xbsa_MountLibrary(&butxInfo, xbsaType); if (rc != XBSA_SUCCESS) { TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n"); return (1); } forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */ if (forcemultiple) printf("Force XBSA multiple server support\n"); rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName); if (rc != XBSA_SUCCESS) return (1); } #endif /*xbsa */ /* cell switch */ if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName)); else cellName[0] = '\0'; if (as->parms[4].items) autoQuery = 0; localauth = (as->parms[5].items ? 1 : 0); rxBind = (as->parms[8].items ? 1 : 0); if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = parseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) host = SHostAddrs[0]; } code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset)); if (code) { TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset); exit(1); } rx_SetRxDeadTime(150); /* Establish connection with the vldb server */ code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires); if (code) { TapeLog(0, 0, code, 0, "Can't access vldb\n"); return code; } strcpy(globalCellName, cellName); /*initialize the dumpNode list */ InitNodeList(portOffset); deviceLatch = (struct deviceSyncNode *)(malloc(sizeof(struct deviceSyncNode))); Lock_Init(&(deviceLatch->lock)); deviceLatch->flags = 0; /* initialize database support, volume support, and logs */ /* Create a single security object, in this case the null security * object, for unauthenticated connections, which will be used to control * security on connections made to this server */ securityObjects[0] = rxnull_NewServerSecurityObject(); securityObjects[1] = (struct rx_securityClass *)0; /* don't bother with rxvab */ if (!securityObjects[0]) { TLog(0, "rxnull_NewServerSecurityObject"); exit(1); } service = rx_NewServiceHost(host, 0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest); if (!service) { TLog(0, "rx_NewService"); exit(1); } rx_SetMaxProcs(service, 4); /* Establish connection to the backup database */ code = udbClientInit(0, localauth, cellName); if (code) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } /* This call is here to verify that we are authentiated. * The call does nothing and will return BUDB_NOTPERMITTED * if we don't belong. */ code = bcdb_deleteDump(0, 0, 0, 0); if (code == BUDB_NOTPERMITTED) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } initStatus(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task"); exit(1); } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task"); exit(1); } AFS_SIGSET_CLEAR(); code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2, "dbWatcher", &dbWatcherPid); #endif if (code) { TapeLog(0, 0, code, 0, "Can't create database monitor task"); exit(1); } TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n", portOffset, debugLevel); TLog(0, "Token expires: %s\n", cTIME(&tokenExpires)); rx_StartServer(1); /* Donate this process to the server process pool */ TLog(0, "Error: StartServer returned"); exit(1); }
static int CommandProc(struct cmd_syndesc *as, void *arock) { krb5_principal princ = 0; char *cell, *pname, **hrealms, *service; char service_temp[MAXKTCREALMLEN + 20]; krb5_creds incred[1], mcred[1], *outcred = 0, *afscred; krb5_ccache cc = 0; #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC krb5_get_init_creds_opt *gic_opts; #else krb5_get_init_creds_opt gic_opts[1]; #endif char *tofree = NULL, *outname; int code; char *what; int i, dosetpag, evil, noprdb, id; #ifdef AFS_RXK5 int authtype; #endif krb5_data enc_part[1]; krb5_prompter_fct pf = NULL; char *pass = 0; void *pa = 0; struct kp_arg klog_arg[1]; char passwd[BUFSIZ]; struct afsconf_cell cellconfig[1]; static char rn[] = "klog"; /*Routine name */ static int Pipe = 0; /* reading from a pipe */ static int Silent = 0; /* Don't want error messages */ int writeTicketFile = 0; /* write ticket file to /tmp */ service = 0; memset(incred, 0, sizeof *incred); /* blow away command line arguments */ for (i = 1; i < zero_argc; i++) memset(zero_argv[i], 0, strlen(zero_argv[i])); zero_argc = 0; memset(klog_arg, 0, sizeof *klog_arg); /* first determine quiet flag based on -silent switch */ Silent = (as->parms[aSILENT].items ? 1 : 0); if (Silent) { afs_set_com_err_hook(silent_errors); } if ((code = krb5_init_context(&k5context))) { afs_com_err(rn, code, "while initializing Kerberos 5 library"); KLOGEXIT(code); } if ((code = rx_Init(0))) { afs_com_err(rn, code, "while initializing rx"); KLOGEXIT(code); } initialize_U_error_table(); /*initialize_krb5_error_table();*/ initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); /* initialize_rx_error_table(); */ if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) { afs_com_err(rn, 0, "can't get afs configuration (afsconf_Open(%s))", AFSDIR_CLIENT_ETC_DIRPATH); KLOGEXIT(1); } /* * Enable DES enctypes, which are currently still required for AFS. * krb5_allow_weak_crypto is MIT Kerberos 1.8. krb5_enctype_enable is * Heimdal. */ #if defined(HAVE_KRB5_ENCTYPE_ENABLE) i = krb5_enctype_valid(k5context, ETYPE_DES_CBC_CRC); if (i) krb5_enctype_enable(k5context, ETYPE_DES_CBC_CRC); #elif defined(HAVE_KRB5_ALLOW_WEAK_CRYPTO) krb5_allow_weak_crypto(k5context, 1); #endif /* Parse remaining arguments. */ dosetpag = !! as->parms[aSETPAG].items; Pipe = !! as->parms[aPIPE].items; writeTicketFile = !! as->parms[aTMP].items; noprdb = !! as->parms[aNOPRDB].items; evil = (always_evil&1) || !! as->parms[aUNWRAP].items; #ifdef AFS_RXK5 authtype = 0; if (as->parms[aK5].items) authtype |= FORCE_RXK5; if (as->parms[aK4].items) authtype |= FORCE_RXKAD; if (!authtype) authtype |= env_afs_rxk5_default(); #endif cell = as->parms[aCELL].items ? as->parms[aCELL].items->data : 0; if ((code = afsconf_GetCellInfo(tdir, cell, "afsprot", cellconfig))) { if (cell) afs_com_err(rn, code, "Can't get cell information for '%s'", cell); else afs_com_err(rn, code, "Can't get determine local cell!"); KLOGEXIT(code); } if (as->parms[aKRBREALM].items) { code = krb5_set_default_realm(k5context, as->parms[aKRBREALM].items->data); if (code) { afs_com_err(rn, code, "Can't make <%s> the default realm", as->parms[aKRBREALM].items->data); KLOGEXIT(code); } } else if ((code = krb5_get_host_realm(k5context, cellconfig->hostName[0], &hrealms))) { afs_com_err(rn, code, "Can't get realm for host <%s> in cell <%s>\n", cellconfig->hostName[0], cellconfig->name); KLOGEXIT(code); } else { if (hrealms && *hrealms) { code = krb5_set_default_realm(k5context, *hrealms); if (code) { afs_com_err(rn, code, "Can't make <%s> the default realm", *hrealms); KLOGEXIT(code); } } if (hrealms) krb5_free_host_realm(k5context, hrealms); } id = getuid(); if (as->parms[aPRINCIPAL].items) { pname = as->parms[aPRINCIPAL].items->data; } else { /* No explicit name provided: use Unix uid. */ struct passwd *pw; pw = getpwuid(id); if (pw == 0) { afs_com_err(rn, 0, "Can't figure out your name from your user id (%d).", id); if (!Silent) fprintf(stderr, "%s: Try providing the user name.\n", rn); KLOGEXIT(1); } pname = pw->pw_name; } code = krb5_parse_name(k5context, pname, &princ); if (code) { afs_com_err(rn, code, "Can't parse principal <%s>", pname); KLOGEXIT(code); } if (as->parms[aPASSWORD].items) { /* * Current argument is the desired password string. Remember it in * our local buffer, and zero out the argument string - anyone can * see it there with ps! */ strncpy(passwd, as->parms[aPASSWORD].items->data, sizeof(passwd)); memset(as->parms[aPASSWORD].items->data, 0, strlen(as->parms[aPASSWORD].items->data)); pass = passwd; } /* Get the password if it wasn't provided. */ if (!pass) { if (Pipe) { strncpy(passwd, getpipepass(), sizeof(passwd)); pass = passwd; } else { pf = klog_prompter; pa = klog_arg; } } service = 0; #ifdef AFS_RXK5 if (authtype & FORCE_RXK5) { tofree = get_afs_krb5_svc_princ(cellconfig); snprintf(service_temp, sizeof service_temp, "%s", tofree); } else #endif snprintf (service_temp, sizeof service_temp, "afs/%s", cellconfig->name); klog_arg->pp = &pass; klog_arg->pstore = passwd; klog_arg->allocated = sizeof(passwd); /* XXX should allow k5 to prompt in most cases -- what about expired pw?*/ #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC code = krb5_get_init_creds_opt_alloc(k5context, &gic_opts); if (code) { afs_com_err(rn, code, "Can't allocate get_init_creds options"); KLOGEXIT(code); } #else krb5_get_init_creds_opt_init(gic_opts); #endif for (;;) { code = krb5_get_init_creds_password(k5context, incred, princ, pass, pf, /* prompter */ pa, /* data */ 0, /* start_time */ 0, /* in_tkt_service */ gic_opts); if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) break; } memset(passwd, 0, sizeof(passwd)); if (code) { char *r = 0; if (krb5_get_default_realm(k5context, &r)) r = 0; if (r) afs_com_err(rn, code, "Unable to authenticate in realm %s", r); else afs_com_err(rn, code, "Unable to authenticate to use cell %s", cellconfig->name); if (r) free(r); KLOGEXIT(code); } for (;;writeTicketFile = 0) { if (writeTicketFile) { what = "getting default ccache"; code = krb5_cc_default(k5context, &cc); } else { what = "krb5_cc_resolve"; code = krb5_cc_resolve(k5context, "MEMORY:core", &cc); if (code) goto Failed; } what = "initializing ccache"; code = krb5_cc_initialize(k5context, cc, princ); if (code) goto Failed; what = "writing Kerberos ticket file"; code = krb5_cc_store_cred(k5context, cc, incred); if (code) goto Failed; if (writeTicketFile) fprintf(stderr, "Wrote ticket file to %s\n", krb5_cc_get_name(k5context, cc)); break; Failed: if (code) afs_com_err(rn, code, "%s", what); if (writeTicketFile) { if (cc) { krb5_cc_close(k5context, cc); cc = 0; } continue; } KLOGEXIT(code); } for (service = service_temp;;service = "afs") { memset(mcred, 0, sizeof *mcred); mcred->client = princ; code = krb5_parse_name(k5context, service, &mcred->server); if (code) { afs_com_err(rn, code, "Unable to parse service <%s>\n", service); KLOGEXIT(code); } if (tofree) { free(tofree); tofree = 0; } if (!(code = krb5_unparse_name(k5context, mcred->server, &outname))) tofree = outname; else outname = service; code = krb5_get_credentials(k5context, 0, cc, mcred, &outcred); krb5_free_principal(k5context, mcred->server); if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || service != service_temp) break; #ifdef AFS_RXK5 if (authtype & FORCE_RXK5) break; #endif } afscred = outcred; if (code) { afs_com_err(rn, code, "Unable to get credentials to use %s", outname); KLOGEXIT(code); } #ifdef AFS_RXK5 if (authtype & FORCE_RXK5) { struct ktc_principal aserver[1]; int viceid = 555; memset(aserver, 0, sizeof *aserver); strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1); code = ktc_SetK5Token(k5context, aserver, afscred, viceid, dosetpag); if (code) { afs_com_err(rn, code, "Unable to store tokens for cell %s\n", cellconfig->name); KLOGEXIT(1); } } else #endif { struct ktc_principal aserver[1], aclient[1]; struct ktc_token atoken[1]; memset(atoken, 0, sizeof *atoken); if (evil) { size_t elen = enc_part->length; atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY; if (afs_krb5_skip_ticket_wrapper(afscred->ticket.data, afscred->ticket.length, (char **) &enc_part->data, &elen)) { afs_com_err(rn, 0, "Can't unwrap %s AFS credential", cellconfig->name); KLOGEXIT(1); } } else { atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5; *enc_part = afscred->ticket; } atoken->startTime = afscred->times.starttime; atoken->endTime = afscred->times.endtime; if (tkt_DeriveDesKey(get_creds_enctype(afscred), get_cred_keydata(afscred), get_cred_keylen(afscred), &atoken->sessionKey)) { afs_com_err(rn, 0, "Cannot derive DES key from enctype %i of length %u", get_creds_enctype(afscred), (unsigned)get_cred_keylen(afscred)); KLOGEXIT(1); } memcpy(atoken->ticket, enc_part->data, atoken->ticketLen = enc_part->length); memset(aserver, 0, sizeof *aserver); strncpy(aserver->name, "afs", 4); strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1); memset(aclient, 0, sizeof *aclient); i = realm_len(k5context, afscred->client); if (i > MAXKTCREALMLEN-1) i = MAXKTCREALMLEN-1; memcpy(aclient->cell, realm_data(k5context, afscred->client), i); if (!noprdb) { int viceid = 0; k5_to_k4_name(k5context, afscred->client, aclient); code = whoami(atoken, cellconfig, aclient, &viceid); if (code) { afs_com_err(rn, code, "Can't get your viceid for cell %s", cellconfig->name); *aclient->name = 0; } else snprintf(aclient->name, MAXKTCNAMELEN-1, "AFS ID %d", viceid); } if (!*aclient->name) k5_to_k4_name(k5context, afscred->client, aclient); code = ktc_SetToken(aserver, atoken, aclient, dosetpag); if (code) { afs_com_err(rn, code, "Unable to store tokens for cell %s\n", cellconfig->name); KLOGEXIT(1); } } krb5_free_principal(k5context, princ); krb5_free_cred_contents(k5context, incred); if (outcred) krb5_free_creds(k5context, outcred); if (cc) krb5_cc_close(k5context, cc); if (tofree) free(tofree); return 0; }
static int WorkerBee(struct cmd_syndesc *as, void *arock) { afs_int32 code, numClasses; struct rx_securityClass *(nullObjects[1]), **secObjs, **allObjs; struct rx_service *service; time_t tokenExpires; char cellName[64]; int localauth; /*process arguments */ afs_int32 portOffset = 0; #ifdef AFS_PTHREAD_ENV pthread_t dbWatcherPid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS dbWatcherPid; #endif char hoststr[16]; afs_uint32 host = htonl(INADDR_ANY); char *auditFileName = NULL; char *auditInterface = NULL; debugLevel = 0; /*initialize the error tables */ initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_BUTM_error_table(); initialize_BUTC_error_table(); #ifdef xbsa initialize_BUTX_error_table(); #endif /*xbs */ initialize_VOLS_error_table(); initialize_BUDB_error_table(); initialize_BUCD_error_table(); if (as->parms[0].items) { portOffset = SafeATOL(as->parms[0].items->data); if (portOffset == -1) { fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data); exit(1); } else if (portOffset > BC_MAXPORTOFFSET) { fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET); exit(1); } } xbsaType = XBSA_SERVER_TYPE_NONE; /* default */ if (as->parms[3].items) { /* -device */ globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */ globalTapeConfig.fileMarkSize = 0; globalTapeConfig.portOffset = portOffset; strncpy(globalTapeConfig.device, as->parms[3].items->data, 100); xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */ } else { /* Search for an entry in tapeconfig file */ code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset); if (code == -1) { fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile); exit(1); } /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so * it's an XBSA server. Don't know if its ADSM or not so its unknown. */ xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE); } if (as->parms[6].items) { /* -restoretofile */ restoretofile = strdup(as->parms[6].items->data); printf("Restore to file '%s'\n", restoretofile); } /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set * the exact xbsaType within the call (won't be unknown) - double check. */ code = GetConfigParams(pFile, portOffset); if (code) exit(code); #ifdef xbsa if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) { printf ("\nConfiguration file error, the TYPE parameter must be specified, or\n"); printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset); exit(1); } #else /* Not compiled for XBSA code so we can't support it */ if (CONF_XBSA) { printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset); printf("This binary does not have XBSA support\n"); exit(1); } #endif /* Open the log files. The pathnames were set in GetConfigParams() */ logIO = fopen(logFile, "a"); if (!logIO) { fprintf(stderr, "Failed to open %s\n", logFile); exit(1); } ErrorlogIO = fopen(ErrorlogFile, "a"); if (!ErrorlogIO) { fprintf(stderr, "Failed to open %s\n", ErrorlogFile); exit(1); } if (lastLog) { lastLogIO = fopen(lastLogFile, "a"); if (!lastLogIO) { fprintf(stderr, "Failed to open %s\n", lastLogFile); exit(1); } } if (centralLogFile) { struct stat sbuf; afs_int32 statcode; #ifndef AFS_NT40_ENV char *path; #endif statcode = stat(centralLogFile, &sbuf); centralLogIO = fopen(centralLogFile, "a"); if (!centralLogIO) { fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile, errno); exit(1); } #ifndef AFS_NT40_ENV /* Make sure it is not in AFS, has to have been created first */ path = malloc(AFSDIR_PATH_MAX); if (path == NULL || !realpath(centralLogFile, path)) { fprintf(stderr, "Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno); } else { if (strncmp(path, "/afs/", 5) == 0) { fprintf(stderr, "The central log '%s' should not be in AFS\n", centralLogFile); exit(1); } } free(path); #endif /* Write header if created it */ if (statcode) { char *h1 = "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n"; char *h2 = "----- ------------------- ------------------- -------- ---------\n"; /* File didn't exist before so write the header lines */ fwrite(h1, strlen(h1), 1, centralLogIO); fwrite(h2, strlen(h2), 1, centralLogIO); fflush(centralLogIO); } } /* Open the configuration directory */ butc_confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (butc_confdir == NULL) { TLog(0, "Failed to open server configuration directory"); exit(1); } /* Start auditing */ osi_audit_init(); if (as->parms[9].items) { auditFileName = as->parms[9].items->data; } if (auditFileName != NULL) osi_audit_file(auditFileName); if (as->parms[10].items) { auditInterface = as->parms[10].items->data; if (osi_audit_interface(auditInterface)) { TLog(0, "Invalid audit interface '%s'\n", auditInterface); exit(1); } } osi_audit(TC_StartEvent, 0, AUD_END); osi_audit_set_user_check(butc_confdir, tc_IsLocalRealmMatch); if (as->parms[1].items) { debugLevel = SafeATOL(as->parms[1].items->data); if (debugLevel == -1) { TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data); exit(1); } } #ifdef xbsa /* Setup XBSA library interface */ if (CONF_XBSA) { afs_int32 rc; rc = xbsa_MountLibrary(&butxInfo, xbsaType); if (rc != XBSA_SUCCESS) { TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n"); return (1); } forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */ if (forcemultiple) printf("Force XBSA multiple server support\n"); rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName); if (rc != XBSA_SUCCESS) return (1); (void)signal(SIGINT, xbsa_shutdown); (void)signal(SIGHUP, xbsa_shutdown); } #endif /*xbsa */ /* cell switch */ if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName)); else cellName[0] = '\0'; if (as->parms[4].items) autoQuery = 0; localauth = (as->parms[5].items ? 1 : 0); rxBind = (as->parms[8].items ? 1 : 0); allow_unauth = (as->parms[11].items ? 1 : 0); if (!allow_unauth && !localauth) { const char *errstr = "Neither -localauth nor -allow_unauthenticated was provided; refusing to start in unintended insecure configuration\n"; TLog(0, "%s", (char *)errstr); exit(1); } if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) host = SHostAddrs[0]; } TLog(0, "butc binding rx to %s:%d\n", afs_inet_ntoa_r(host, hoststr), BC_TAPEPORT + portOffset); code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset)); if (code) { TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset); exit(1); } rx_SetRxDeadTime(150); /* Establish connection with the vldb server */ code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires); if (code) { TapeLog(0, 0, code, 0, "Can't access vldb\n"); return code; } strcpy(globalCellName, cellName); /*initialize the dumpNode list */ InitNodeList(portOffset); deviceLatch = malloc(sizeof(struct deviceSyncNode)); Lock_Init(&(deviceLatch->lock)); deviceLatch->flags = 0; /* initialize database support, volume support, and logs */ /* * Create security objects for the Rx server functionality. Historically * this was a single rxnull security object, since the tape controller was * run by an operator that had local access to the tape device and some * administrative privilege in the cell (to be able to perform volume-level * accesses), but on a machine that was not necessarily trusted to hold the * cell-wide key. * * Such a configuration is, of course, insecure because anyone can make * inbound RPCs and manipulate the database, including creating bogus * dumps and restoring them! Additionally, in modern usage, butc is * frequently run with -localauth to authenticate its outbound connections * to the volservers and budb with the cell-wide key, in which case the * cell-wide key is present and could be used to authenticate incoming * connections as well. * * If -localauth is in use, create the full barrage of server security * objects, including rxkad, so that inbound connections can be verified * to only be made by authenticated clients. Otherwise, only the rxnull * class is in use with a single server security object. Note that butc * will refuse to start in this configuration unless the * "-allow_unauthenticated" flag is provided, indicating that the operator * has ensured that incoming connections are appropriately restricted by * firewall configuration or network topology. */ if (allow_unauth) { nullObjects[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject(); if (!nullObjects[RX_SECIDX_NULL]) { TLog(0, "rxnull_NewServerSecurityObject"); exit(1); } numClasses = 1; secObjs = nullObjects; } else { /* Must be -localauth, so the cell keys are available. */ afsconf_BuildServerSecurityObjects(butc_confdir, &allObjs, &numClasses); secObjs = allObjs; } service = rx_NewServiceHost(host, 0, 1, "BUTC", secObjs, numClasses, TC_ExecuteRequest); if (!service) { TLog(0, "rx_NewService"); exit(1); } rx_SetMaxProcs(service, 4); /* Establish connection to the backup database */ code = udbClientInit(0, localauth, cellName); if (code) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } /* This call is here to verify that we are authentiated. * The call does nothing and will return BUDB_NOTPERMITTED * if we don't belong. */ code = bcdb_deleteDump(0, 0, 0, 0); if (code == BUDB_NOTPERMITTED) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } initStatus(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task"); exit(1); } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task"); exit(1); } AFS_SIGSET_CLEAR(); code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2, "dbWatcher", &dbWatcherPid); #endif if (code) { TapeLog(0, 0, code, 0, "Can't create database monitor task"); exit(1); } TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n", portOffset, debugLevel); TLog(0, "Token expires: %s\n", cTIME(&tokenExpires)); rx_StartServer(1); /* Donate this process to the server process pool */ TLog(0, "Error: StartServer returned"); exit(1); }