Ejemplo n.º 1
0
static void
do_client(const char *server, short port, char *filename, afs_int32 command,
          afs_int32 times, afs_int32 bytes, afs_int32 sendbytes, afs_int32 readbytes,
          int dumpstats, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
          int udpbufsz, int nostats, int hotthread, int threads)
{
    struct rx_connection *conn;
    afs_uint32 addr;
    struct rx_securityClass *secureobj;
    int secureindex;
    int ret;
    char stamp[2048];
    struct client_data *params;

#ifdef AFS_PTHREAD_ENV
    int i;
    pthread_t thread[MAX_THREADS];
    pthread_attr_t tattr;
    void *status;
#endif

    params = malloc(sizeof(struct client_data));
    memset(params, 0, sizeof(struct client_data));

#ifdef AFS_NT40_ENV
    if (afs_winsockInit() < 0) {
        printf("Can't initialize winsock.\n");
        exit(1);
    }
#endif

    if (hotthread)
        rx_EnableHotThread();

    if (nostats)
        rx_enable_stats = 0;

    addr = str2addr(server);

    rx_SetUdpBufSize(udpbufsz);

    ret = rx_Init(0);
    if (ret)
        errx(1, "rx_Init failed");

    if (nojumbo)
        rx_SetNoJumbo();

    if (maxmtu)
        rx_SetMaxMTU(maxmtu);

    if (maxwsize) {
        rx_SetMaxReceiveWindow(maxwsize);
        rx_SetMaxSendWindow(maxwsize);
    }

    if (minpeertimeout)
        rx_SetMinPeerTimeout(minpeertimeout);


    get_sec(0, &secureobj, &secureindex);

    switch (command) {
    case RX_PERF_RPC:
        sprintf(stamp, "RPC: threads\t%d, times\t%d, write bytes\t%d, read bytes\t%d",
                threads, times, sendbytes, readbytes);
        break;
    case RX_PERF_RECV:
        sprintf(stamp, "RECV: threads\t%d, times\t%d, bytes\t%d",
                threads, times, bytes);
        break;
    case RX_PERF_SEND:
        sprintf(stamp, "SEND: threads\t%d, times\t%d, bytes\t%d",
                threads, times, bytes);
        break;
    case RX_PERF_FILE:
        sprintf(stamp, "FILE %s: threads\t%d, times\t%d, bytes\t%d",
                filename, threads, times, bytes);
        break;
    }

    conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
    if (conn == NULL)
        errx(1, "failed to contact server");

#ifdef AFS_PTHREAD_ENV
    pthread_attr_init(&tattr);
    pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
#endif

    params->conn = conn;
    params->filename = filename;
    params->command = command;
    params->times = times;
    params->bytes = bytes;
    params->sendbytes = sendbytes;
    params->readbytes = readbytes;

    start_timer();

#ifdef AFS_PTHREAD_ENV
    for ( i=0; i<threads; i++) {
        pthread_create(&thread[i], &tattr, client_thread, params);
        if ( (i + 1) % RX_MAXCALLS == 0 ) {
            conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
            if (conn != NULL) {
                struct client_data *new_params = malloc(sizeof(struct client_data));
                memcpy(new_params, params, sizeof(struct client_data));
                new_params->conn = conn;
                params = new_params;
            }
        }
    }
#else
    client_thread(params);
#endif

#ifdef AFS_PTHREAD_ENV
    for ( i=0; i<threads; i++)
        pthread_join(thread[i], &status);
#endif

    switch (command) {
    case RX_PERF_RPC:
        end_and_print_timer(stamp, (long long)threads*times*(sendbytes+readbytes));
        break;
    case RX_PERF_RECV:
    case RX_PERF_SEND:
    case RX_PERF_FILE:
        end_and_print_timer(stamp, (long long)threads*times*bytes);
        break;
    }

    DBFPRINT(("done for good\n"));

    if (dumpstats) {
        rx_PrintStats(stdout);
        rx_PrintPeerStats(stdout, conn->peer);
    }
    rx_Finalize();

#ifdef AFS_PTHREAD_ENV
    pthread_attr_destroy(&tattr);
#endif

    free(params);
}
Ejemplo n.º 2
0
int
main(int argc, char **argv, char **envp)
{
    struct rx_service *tservice;
    afs_int32 code;
    struct afsconf_dir *tdir;
    int noAuth = 0;
    int i;
    char namebuf[AFSDIR_PATH_MAX];
    int rxMaxMTU = -1;
    afs_uint32 host = htonl(INADDR_ANY);
    char *auditFileName = NULL;
    struct rx_securityClass **securityClasses;
    afs_int32 numClasses;
#ifndef AFS_NT40_ENV
    int nofork = 0;
    struct stat sb;
#endif
#ifdef	AFS_AIX32_ENV
    struct sigaction nsa;

    /* for some reason, this permits user-mode RX to run a lot faster.
     * we do it here in the bosserver, so we don't have to do it
     * individually in each server.
     */
    tweak_config();

    /*
     * 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.
     */
    sigemptyset(&nsa.sa_mask);
    nsa.sa_handler = SIG_DFL;
    nsa.sa_flags = SA_FULLDUMP;
    sigaction(SIGSEGV, &nsa, NULL);
    sigaction(SIGABRT, &nsa, NULL);
#endif
    osi_audit_init();
    signal(SIGFPE, bozo_insecureme);

#ifdef AFS_NT40_ENV
    /* Initialize winsock */
    if (afs_winsockInit() < 0) {
	ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
	fprintf(stderr, "%s: Couldn't initialize winsock.\n", argv[0]);
	exit(2);
    }
#endif

    /* Initialize dirpaths */
    if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
#ifdef AFS_NT40_ENV
	ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
#endif
	fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
		argv[0]);
	exit(2);
    }

    /* some path inits */
    bozo_fileName = AFSDIR_SERVER_BOZCONF_FILEPATH;
    DoCore = AFSDIR_SERVER_LOGS_DIRPATH;

    /* initialize the list of dirpaths that the bosserver has
     * an interest in monitoring */
    initBosEntryStats();

#if defined(AFS_SGI_ENV)
    /* offer some protection if AFS isn't loaded */
    if (syscall(AFS_SYSCALL, AFSOP_ENDLOG) < 0 && errno == ENOPKG) {
	printf("bosserver: AFS doesn't appear to be configured in O.S..\n");
	exit(1);
    }
#endif

#ifndef AFS_NT40_ENV
    /* save args for restart */
    bozo_argc = argc;
    bozo_argv = malloc((argc+1) * sizeof(char*));
    if (!bozo_argv) {
	fprintf(stderr, "%s: Failed to allocate argument list.\n", argv[0]);
	exit(1);
    }
    bozo_argv[0] = (char*)AFSDIR_SERVER_BOSVR_FILEPATH; /* expected path */
    bozo_argv[bozo_argc] = NULL; /* null terminate list */
#endif	/* AFS_NT40_ENV */

    /* parse cmd line */
    for (code = 1; code < argc; code++) {
#ifndef AFS_NT40_ENV
	bozo_argv[code] = argv[code];
#endif	/* AFS_NT40_ENV */
	if (strcmp(argv[code], "-noauth") == 0) {
	    /* set noauth flag */
	    noAuth = 1;
	} else if (strcmp(argv[code], "-log") == 0) {
	    /* set extra logging flag */
	    DoLogging = 1;
	}
#ifndef AFS_NT40_ENV
	else if (strcmp(argv[code], "-syslog") == 0) {
	    /* set syslog logging flag */
	    DoSyslog = 1;
	} else if (strncmp(argv[code], "-syslog=", 8) == 0) {
	    DoSyslog = 1;
	    DoSyslogFacility = atoi(argv[code] + 8);
	} else if (strncmp(argv[code], "-cores=", 7) == 0) {
	    if (strcmp((argv[code]+7), "none") == 0)
		DoCore = 0;
	    else
		DoCore = (argv[code]+7);
	} else if (strcmp(argv[code], "-nofork") == 0) {
	    nofork = 1;
	}
#endif
	else if (strcmp(argv[code], "-enable_peer_stats") == 0) {
	    rx_enablePeerRPCStats();
	} else if (strcmp(argv[code], "-enable_process_stats") == 0) {
	    rx_enableProcessRPCStats();
	}
	else if (strcmp(argv[code], "-restricted") == 0) {
	    bozo_isrestricted = 1;
	}
	else if (strcmp(argv[code], "-rxbind") == 0) {
	    rxBind = 1;
	}
	else if (strcmp(argv[code], "-allow-dotted-principals") == 0) {
	    rxkadDisableDotCheck = 1;
	}
	else if (!strcmp(argv[code], "-rxmaxmtu")) {
	    if ((code + 1) >= argc) {
		fprintf(stderr, "missing argument for -rxmaxmtu\n");
		exit(1);
	    }
	    rxMaxMTU = atoi(argv[++code]);
	}
	else if (strcmp(argv[code], "-auditlog") == 0) {
	    auditFileName = argv[++code];

	} else if (strcmp(argv[code], "-audit-interface") == 0) {
	    char *interface = argv[++code];

	    if (osi_audit_interface(interface)) {
		printf("Invalid audit interface '%s'\n", interface);
		exit(1);
	    }
	} else if (strncmp(argv[code], "-pidfiles=", 10) == 0) {
	    DoPidFiles = (argv[code]+10);
	} else if (strncmp(argv[code], "-pidfiles", 9) == 0) {
	    DoPidFiles = AFSDIR_BOSCONFIG_DIR;
	}
	else {

	    /* hack to support help flag */

#ifndef AFS_NT40_ENV
	    printf("Usage: bosserver [-noauth] [-log] "
		   "[-auditlog <log path>] "
		   "[-audit-interafce <file|sysvmq> (default is file)] "
		   "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals]"
		   "[-syslog[=FACILITY]] "
		   "[-restricted] "
		   "[-enable_peer_stats] [-enable_process_stats] "
		   "[-cores=<none|path>] \n"
		   "[-pidfiles[=path]] "
		   "[-nofork] " "[-help]\n");
#else
	    printf("Usage: bosserver [-noauth] [-log] "
		   "[-auditlog <log path>] "
		   "[-audit-interafce <file|sysvmq> (default is file)] "
		   "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals]"
		   "[-restricted] "
		   "[-enable_peer_stats] [-enable_process_stats] "
		   "[-cores=<none|path>] \n"
		   "[-pidfiles[=path]] "
		   "[-help]\n");
#endif
	    fflush(stdout);

	    exit(0);
	}
    }
    if (auditFileName) {
	osi_audit_file(auditFileName);
    }

#ifndef AFS_NT40_ENV
    if (geteuid() != 0) {
	printf("bosserver: must be run as root.\n");
	exit(1);
    }
#endif

    code = bnode_Init();
    if (code) {
	printf("bosserver: could not init bnode package, code %d\n", code);
	exit(1);
    }

    bnode_Register("fs", &fsbnode_ops, 3);
    bnode_Register("dafs", &dafsbnode_ops, 4);
    bnode_Register("simple", &ezbnode_ops, 1);
    bnode_Register("cron", &cronbnode_ops, 2);

    /* create useful dirs */
    CreateDirs(DoCore);

    /* chdir to AFS log directory */
    if (DoCore)
	chdir(DoCore);
    else
	chdir(AFSDIR_SERVER_LOGS_DIRPATH);

#if 0
    fputs(AFS_GOVERNMENT_MESSAGE, stdout);
    fflush(stdout);
#endif

    /* go into the background and remove our controlling tty, close open
       file desriptors
     */

#ifndef AFS_NT40_ENV
    if (!nofork)
	daemon(1, 0);
#endif /* ! AFS_NT40_ENV */

    if ((!DoSyslog)
#ifndef AFS_NT40_ENV
	&& ((lstat(AFSDIR_BOZLOG_FILE, &sb) == 0) &&
	!(S_ISFIFO(sb.st_mode)))
#endif
	) {
	strcpy(namebuf, AFSDIR_BOZLOG_FILE);
	strcat(namebuf, ".old");
	renamefile(AFSDIR_BOZLOG_FILE, namebuf);	/* try rename first */
	bozo_logFile = fopen(AFSDIR_BOZLOG_FILE, "a");
	if (!bozo_logFile) {
	    printf("bosserver: can't initialize log file (%s).\n",
		   AFSDIR_SERVER_BOZLOG_FILEPATH);
	    exit(1);
	}
	/* keep log closed normally, so can be removed */
	fclose(bozo_logFile);
    } else {
#ifndef AFS_NT40_ENV
	openlog("bosserver", LOG_PID, DoSyslogFacility);
#endif
    }

#if defined(RLIMIT_CORE) && defined(HAVE_GETRLIMIT)
    {
      struct rlimit rlp;
      getrlimit(RLIMIT_CORE, &rlp);
      if (!DoCore)
	  rlp.rlim_cur = 0;
      else
	  rlp.rlim_max = rlp.rlim_cur = RLIM_INFINITY;
      setrlimit(RLIMIT_CORE, &rlp);
      getrlimit(RLIMIT_CORE, &rlp);
      bozo_Log("Core limits now %d %d\n",(int)rlp.rlim_cur,(int)rlp.rlim_max);
    }
#endif

    /* Write current state of directory permissions to log file */
    DirAccessOK();

    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];
    }

    for (i = 0; i < 10; i++) {
	if (rxBind) {
	    code = rx_InitHost(host, htons(AFSCONF_NANNYPORT));
	} else {
	    code = rx_Init(htons(AFSCONF_NANNYPORT));
	}
	if (code) {
	    bozo_Log("can't initialize rx: code=%d\n", code);
	    sleep(3);
	} else
	    break;
    }
    if (i >= 10) {
	bozo_Log("Bos giving up, can't initialize rx\n");
	exit(code);
    }

    /* Disable jumbograms */
    rx_SetNoJumbo();

    if (rxMaxMTU != -1) {
	if (rx_SetMaxMTU(rxMaxMTU) != 0) {
	    bozo_Log("bosserver: rxMaxMTU %d is invalid\n", rxMaxMTU);
	    exit(1);
	}
    }

    code = LWP_CreateProcess(BozoDaemon, BOZO_LWP_STACKSIZE, /* priority */ 1,
			     /* param */ NULL , "bozo-the-clown",
			     &bozo_pid);

    /* try to read the key from the config file */
    tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
    if (!tdir) {
	/* try to create local cell config file */
	struct afsconf_cell tcell;
	strcpy(tcell.name, "localcell");
	tcell.numServers = 1;
	code = gethostname(tcell.hostName[0], MAXHOSTCHARS);
	if (code) {
	    bozo_Log("failed to get hostname, code %d\n", errno);
	    exit(1);
	}
	if (tcell.hostName[0][0] == 0) {
	    bozo_Log("host name not set, can't start\n");
	    bozo_Log("try the 'hostname' command\n");
	    exit(1);
	}
	memset(tcell.hostAddr, 0, sizeof(tcell.hostAddr));	/* not computed */
	code =
	    afsconf_SetCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
				&tcell);
	if (code) {
	    bozo_Log
		("could not create cell database in '%s' (code %d), quitting\n",
		 AFSDIR_SERVER_ETC_DIRPATH, code);
	    exit(1);
	}
	tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
	if (!tdir) {
	    bozo_Log
		("failed to open newly-created cell database, quitting\n");
	    exit(1);
	}
    }

    /* initialize audit user check */
    osi_audit_set_user_check(tdir, bozo_IsLocalRealmMatch);

    /* read init file, starting up programs */
    if ((code = ReadBozoFile(0))) {
	bozo_Log
	    ("bosserver: Something is wrong (%d) with the bos configuration file %s; aborting\n",
	     code, AFSDIR_SERVER_BOZCONF_FILEPATH);
	exit(code);
    }

    bozo_CreateRxBindFile(host);	/* for local scripts */

    /* opened the cell databse */
    bozo_confdir = tdir;

    /* allow super users to manage RX statistics */
    rx_SetRxStatUserOk(bozo_rxstat_userok);

    afsconf_SetNoAuthFlag(tdir, noAuth);
    afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses);

    if (DoPidFiles) {
	bozo_CreatePidFile("bosserver", NULL, getpid());
    }

    tservice = rx_NewServiceHost(host, 0, /* service id */ 1,
			         "bozo", securityClasses, numClasses,
				 BOZO_ExecuteRequest);
    rx_SetMinProcs(tservice, 2);
    rx_SetMaxProcs(tservice, 4);
    rx_SetStackSize(tservice, BOZO_LWP_STACKSIZE);	/* so gethostbyname works (in cell stuff) */
    if (rxkadDisableDotCheck) {
        rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
                                    (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
    }

    tservice =
	rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats",
			  securityClasses, numClasses, RXSTATS_ExecuteRequest);
    rx_SetMinProcs(tservice, 2);
    rx_SetMaxProcs(tservice, 4);
    rx_StartServer(1);		/* donate this process */
    return 0;
}
Ejemplo n.º 3
0
static void
do_server(short port, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
          int udpbufsz, int nostats, int hotthread,
          int minprocs, int maxprocs)
{
    struct rx_service *service;
    struct rx_securityClass *secureobj;
    int secureindex;
    int ret;

#ifdef AFS_NT40_ENV
    if (afs_winsockInit() < 0) {
        printf("Can't initialize winsock.\n");
        exit(1);
    }
#endif

    if (hotthread)
        rx_EnableHotThread();

    if (nostats)
        rx_enable_stats = 0;

    rx_SetUdpBufSize(udpbufsz);

    ret = rx_Init(htons(port));
    if (ret)
        errx(1, "rx_Init failed");

    if (nojumbo)
        rx_SetNoJumbo();

    if (maxmtu)
        rx_SetMaxMTU(maxmtu);

    if (maxwsize) {
        rx_SetMaxReceiveWindow(maxwsize);
        rx_SetMaxSendWindow(maxwsize);
    }

    if (minpeertimeout)
        rx_SetMinPeerTimeout(minpeertimeout);


    get_sec(1, &secureobj, &secureindex);

    service =
        rx_NewService(0, RX_SERVER_ID, "rxperf", &secureobj, secureindex,
                      rxperf_ExecuteRequest);
    if (service == NULL)
        errx(1, "Cant create server");

    rx_SetMinProcs(service, minprocs);
    rx_SetMaxProcs(service, maxprocs);

    rx_SetCheckReach(service, 1);

    rx_StartServer(1);

    abort();
}
Ejemplo n.º 4
0
int
fsprobe_Init(int a_numServers, struct sockaddr_in *a_socketArray, 
	     int a_ProbeFreqInSecs, int (*a_ProbeHandler)(void),
	     int a_debug)
{				/*fsprobe_Init */

    static char rn[] = "fsprobe_Init";	/*Routine name */
    register afs_int32 code;	/*Return value */
    static struct rx_securityClass *CBsecobj;	/*Callback security object */
    struct rx_securityClass *secobj;	/*Client security object */
    struct rx_service *rxsrv_afsserver;	/*Server for AFS */
    int arg_errfound;		/*Argument error found? */
    int curr_srv;		/*Current server idx */
    struct fsprobe_ConnectionInfo *curr_conn;	/*Ptr to current conn */
    char *hostNameFound;	/*Ptr to returned host name */
    int conn_err;		/*Connection error? */
    int PortToUse;		/*Callback port to use */

    /*
     * If we've already been called, snicker at the bozo, gently
     * remind him of his doubtful heritage, and return success.
     */
    if (fsprobe_initflag) {
	fprintf(stderr, "[%s] Called multiple times!\n", rn);
	return (0);
    } else
	fsprobe_initflag = 1;

    /*
     * Check the parameters for bogosities.
     */
    arg_errfound = 0;
    if (a_numServers <= 0) {
	fprintf(stderr, "[%s] Illegal number of servers: %d\n", rn,
		a_numServers);
	arg_errfound = 1;
    }
    if (a_socketArray == (struct sockaddr_in *)0) {
	fprintf(stderr, "[%s] Null server socket array argument\n", rn);
	arg_errfound = 1;
    }
    if (a_ProbeFreqInSecs <= 0) {
	fprintf(stderr, "[%s] Illegal probe frequency: %d\n", rn,
		a_ProbeFreqInSecs);
	arg_errfound = 1;
    }
    if (a_ProbeHandler == (int (*)())0) {
	fprintf(stderr, "[%s] Null probe handler function argument\n", rn);
	arg_errfound = 1;
    }
    if (arg_errfound)
	return (-1);

    /*
     * Record our passed-in info.
     */
    fsprobe_debug = a_debug;
    fsprobe_numServers = a_numServers;
    fsprobe_Handler = a_ProbeHandler;
    fsprobe_ProbeFreqInSecs = a_ProbeFreqInSecs;

    /*
     * Get ready in case we have to do a cleanup - basically, zero
     * everything out.
     */
    fsprobe_CleanupInit();

    /*
     * Allocate the necessary data structures and initialize everything
     * else.
     */
    fsprobe_ConnInfo = (struct fsprobe_ConnectionInfo *)
	malloc(a_numServers * sizeof(struct fsprobe_ConnectionInfo));
    if (fsprobe_ConnInfo == (struct fsprobe_ConnectionInfo *)0) {
	fprintf(stderr,
		"[%s] Can't allocate %d connection info structs (%"AFS_SIZET_FMT" bytes)\n",
		rn, a_numServers,
		(a_numServers * sizeof(struct fsprobe_ConnectionInfo)));
	return (-1);		/*No cleanup needs to be done yet */
    }
#if 0
    else
	fprintf(stderr, "[%s] fsprobe_ConnInfo allocated (%d bytes)\n", rn,
		a_numServers * sizeof(struct fsprobe_ConnectionInfo));
#endif /* 0 */

    fsprobe_statsBytes = a_numServers * sizeof(struct ProbeViceStatistics);
    fsprobe_Results.stats = (struct ProbeViceStatistics *)
	malloc(fsprobe_statsBytes);
    if (fsprobe_Results.stats == NULL) {
	fprintf(stderr,
		"[%s] Can't allocate %d statistics structs (%d bytes)\n", rn,
		a_numServers, fsprobe_statsBytes);
	fsprobe_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    } else if (fsprobe_debug)
	fprintf(stderr, "[%s] fsprobe_Results.stats allocated (%d bytes)\n",
		rn, fsprobe_statsBytes);

    fsprobe_probeOKBytes = a_numServers * sizeof(int);
    fsprobe_Results.probeOK = (int *)malloc(fsprobe_probeOKBytes);
    if (fsprobe_Results.probeOK == (int *)0) {
	fprintf(stderr,
		"[%s] Can't allocate %d probeOK array entries (%d bytes)\n",
		rn, a_numServers, fsprobe_probeOKBytes);
	fsprobe_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    } else if (fsprobe_debug)
	fprintf(stderr, "[%s] fsprobe_Results.probeOK allocated (%d bytes)\n",
		rn, fsprobe_probeOKBytes);

    fsprobe_Results.probeNum = 0;
    fsprobe_Results.probeTime = 0;
    memset(fsprobe_Results.stats, 0,
	   (a_numServers * sizeof(struct ProbeViceStatistics)));

    /*
     * Initialize the Rx subsystem, just in case nobody's done it.
     */
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Initializing Rx\n", rn);
    PortToUse = FSPROBE_CBPORT;
    do {
	code = rx_Init(htons(PortToUse));
	if (code) {
	    if (code == RX_ADDRINUSE) {
		if (fsprobe_debug)
		    fprintf(stderr,
			    "[%s] Callback port %d in use, advancing\n", rn,
			    PortToUse);
		PortToUse++;
	    } else {
		fprintf(stderr, "[%s] Fatal error in rx_Init()\n", rn);
		return (-1);
	    }
	}
    } while (code);
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Rx initialized on port %d\n", rn, PortToUse);

    /*
     * Create a null Rx server security object, to be used by the
     * Callback listener.
     */
    CBsecobj = rxnull_NewServerSecurityObject();
    if (CBsecobj == (struct rx_securityClass *)0) {
	fprintf(stderr,
		"[%s] Can't create null security object for the callback listener.\n",
		rn);
	fsprobe_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    }
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Callback server security object created\n", rn);

    /*
     * Create a null Rx client security object, to be used by the
     * probe LWP.
     */
    secobj = rxnull_NewClientSecurityObject();
    if (secobj == (struct rx_securityClass *)0) {
	fprintf(stderr,
		"[%s] Can't create client security object for probe LWP.\n",
		rn);
	fsprobe_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    }
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Probe LWP client security object created\n",
		rn);

    curr_conn = fsprobe_ConnInfo;
    conn_err = 0;
    for (curr_srv = 0; curr_srv < a_numServers; curr_srv++) {
	/*
	 * Copy in the socket info for the current server, resolve its
	 * printable name if possible.
	 */
	if (fsprobe_debug) {
	    fprintf(stderr, "[%s] Copying in the following socket info:\n",
		    rn);
	    fprintf(stderr, "[%s] IP addr 0x%x, port %d\n", rn,
		    (a_socketArray + curr_srv)->sin_addr.s_addr,
		    (a_socketArray + curr_srv)->sin_port);
	}
	memcpy(&(curr_conn->skt), a_socketArray + curr_srv,
	       sizeof(struct sockaddr_in));

	hostNameFound =
	    hostutil_GetNameByINet(curr_conn->skt.sin_addr.s_addr);
	if (hostNameFound == NULL) {
	    fprintf(stderr,
		    "[%s] Can't map Internet address %u to a string name\n",
		    rn, curr_conn->skt.sin_addr.s_addr);
	    curr_conn->hostName[0] = '\0';
	} else {
	    strcpy(curr_conn->hostName, hostNameFound);
	    if (fsprobe_debug)
		fprintf(stderr, "[%s] Host name for server index %d is %s\n",
			rn, curr_srv, curr_conn->hostName);
	}

	/*
	 * Make an Rx connection to the current server.
	 */
	if (fsprobe_debug)
	    fprintf(stderr,
		    "[%s] Connecting to srv idx %d, IP addr 0x%x, port %d, service 1\n",
		    rn, curr_srv, curr_conn->skt.sin_addr.s_addr,
		    curr_conn->skt.sin_port);
	curr_conn->rxconn = rx_NewConnection(curr_conn->skt.sin_addr.s_addr,	/*Server addr */
					     curr_conn->skt.sin_port,	/*Server port */
					     1,	/*AFS service num */
					     secobj,	/*Security object */
					     0);	/*Number of above */
	if (curr_conn->rxconn == (struct rx_connection *)0) {
	    fprintf(stderr,
		    "[%s] Can't create Rx connection to server %s (%u)\n",
		    rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr);
	    conn_err = 1;
	}
	if (fsprobe_debug)
	    fprintf(stderr, "[%s] New connection at %p\n", rn,
		    curr_conn->rxconn);

	/*
	 * Make an Rx connection to the current volume server.
	 */
	if (fsprobe_debug)
	    fprintf(stderr,
		    "[%s] Connecting to srv idx %d, IP addr 0x%x, port %d, service 1\n",
		    rn, curr_srv, curr_conn->skt.sin_addr.s_addr,
		    htons(7005));
	curr_conn->rxVolconn = rx_NewConnection(curr_conn->skt.sin_addr.s_addr,	/*Server addr */
						htons(AFSCONF_VOLUMEPORT),	/*Volume Server port */
						VOLSERVICE_ID,	/*AFS service num */
						secobj,	/*Security object */
						0);	/*Number of above */
	if (curr_conn->rxVolconn == (struct rx_connection *)0) {
	    fprintf(stderr,
		    "[%s] Can't create Rx connection to volume server %s (%u)\n",
		    rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr);
	    conn_err = 1;
	} else {
	    int i, cnt;

	    memset(&curr_conn->partList, 0, sizeof(struct partList));
	    curr_conn->partCnt = 0;
	    i = XListPartitions(curr_conn->rxVolconn, &curr_conn->partList,
				&cnt);
	    if (!i) {
		curr_conn->partCnt = cnt;
	    }
	}
	if (fsprobe_debug)
	    fprintf(stderr, "[%s] New connection at %p\n", rn,
		    curr_conn->rxVolconn);


	/*
	 * Bump the current fsprobe connection to set up.
	 */
	curr_conn++;

    }				/*for curr_srv */

    /*
     * Create the AFS callback service (listener).
     */
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Creating AFS callback listener\n", rn);
    rxsrv_afsserver = rx_NewService(0,	/*Use default port */
				    1,	/*Service ID */
				    "afs",	/*Service name */
				    &CBsecobj,	/*Ptr to security object(s) */
				    1,	/*Number of security objects */
				    RXAFSCB_ExecuteRequest);	/*Dispatcher */
    if (rxsrv_afsserver == (struct rx_service *)0) {
	fprintf(stderr, "[%s] Can't create callback Rx service/listener\n",
		rn);
	fsprobe_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    }
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Callback listener created\n", rn);

    /*
     * Start up the AFS callback service.
     */
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Starting up callback listener.\n", rn);
    rx_StartServer(0 /*Don't donate yourself to LWP pool */ );

    /*
     * Start up the probe LWP.
     */
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Creating the probe LWP\n", rn);
    code = LWP_CreateProcess(fsprobe_LWP,	/*Function to start up */
			     LWP_STACK_SIZE,	/*Stack size in bytes */
			     1,	/*Priority */
			     (void *)0,	/*Parameters */
			     "fsprobe Worker",	/*Name to use */
			     &probeLWP_ID);	/*Returned LWP process ID */
    if (code) {
	fprintf(stderr, "[%s] Can't create fsprobe LWP!  Error is %d\n", rn,
		code);
	fsprobe_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (code);
    }
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Probe LWP process structure located at %p\n",
		rn, probeLWP_ID);

#if 0
    /*
     * Do I need to do this?
     */
    if (fsprobe_debug)
	fprintf(stderr, "[%s] Calling osi_Wakeup()\n", rn);
    osi_Wakeup(&rxsrv_afsserver);	/*Wake up anyone waiting for it */
#endif /* 0 */

    /*
     * Return the final results.
     */
    if (conn_err)
	return (-2);
    else
	return (0);

}				/*fsprobe_Init */
Ejemplo n.º 5
0
void
startClient(char *configPath)
{
    struct afsconf_dir *dir;
    struct rx_identity *testId, *anotherId, *extendedId, *dummy;
    struct rx_securityClass *class;
    struct rx_connection *conn;
    afs_uint32 startTime;
    char ubuffer[256];
    afs_int32 classIndex;
    int code;
    struct hostent *he;
    afs_uint32 addr;
    afs_int32 result;
    char *string = NULL;

    plan(63);

    dir = afsconf_Open(configPath);
    ok(dir!=NULL,
       "Configuration directory opened sucessfully by client");

    /* Add a normal user to the super user file */
    ok(afsconf_AddUser(dir, "test") == 0,
       "Adding a simple user works");

    testId = rx_identity_new(RX_ID_KRB4, "test", "test", strlen("test"));

    /* Check that they are a super user */
    ok(afsconf_IsSuperIdentity(dir, testId),
       "User added with old i/face is identitifed as super user");

    /* Check that nobody else is */
    ok(!afsconf_IsSuperIdentity(dir,
			       rx_identity_new(RX_ID_KRB4, "testy",
					       "testy", strlen("testy"))),
       "Additional users are not super users");

    ok(afsconf_AddUser(dir, "test") == EEXIST,
       "Adding a user that already exists fails");

    ok(afsconf_AddIdentity(dir, testId) == EEXIST,
       "Adding an identity that already exists fails");

    anotherId = rx_identity_new(RX_ID_KRB4, "another",
					    "another", strlen("another"));

    /* Add another normal user, but using the extended interface */
    ok(afsconf_AddIdentity(dir, anotherId) == 0,
       "Adding a KRB4 identity works");

    /* Check that they are a super user */
    ok(afsconf_IsSuperIdentity(dir, anotherId),
       "User added with new i/face is identitifed as super user");

    ok(afsconf_AddIdentity(dir, anotherId) == EEXIST,
       "Adding a KRB4 identity that already exists fails");

    /* Add an extended user to the super user file */
    extendedId = rx_identity_new(RX_ID_GSS, "*****@*****.**",
				 "\x04\x01\x00\x0B\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x00\x00\x00\[email protected]", 35);

    ok(afsconf_AddIdentity(dir, extendedId) == 0,
       "Adding a GSSAPI identity works");

    /* Check that they are now special */
    ok(afsconf_IsSuperIdentity(dir, extendedId),
       "Added GSSAPI identity is a super user");

    /* Check that display name isn't used for matches */
    ok(!afsconf_IsSuperIdentity(dir,
				rx_identity_new(RX_ID_GSS, "*****@*****.**",
						"abcdefghijklmnopqrstuvwxyz123456789", 35)),
       "Display name is not used for extended matches");

    ok(afsconf_AddIdentity(dir, extendedId) == EEXIST,
       "Adding GSSAPI identity twice fails");

    /* Add a final normal user, so we can check that iteration works */
    /* Add a normal user to the super user file */
    ok(afsconf_AddUser(dir, "test2") == 0,
       "Adding another simple user works");

    testOriginalIterator(dir, 0, "test");
    testOriginalIterator(dir, 1, "another");
    testOriginalIterator(dir, 2, "test2");
    ok(afsconf_GetNthUser(dir, 3, ubuffer, sizeof ubuffer) != 0,
       "Reading past the end of the superuser list fails");

    testNewIterator(dir, 0, testId);
    testNewIterator(dir, 1, anotherId);
    testNewIterator(dir, 2, extendedId);
    testNewIterator(dir, 3, rx_identity_new(RX_ID_KRB4, "test2",
					    "test2", strlen("test2")));
    ok(afsconf_GetNthIdentity(dir, 4, &dummy) != 0,
       "Reading past the end of the superuser list fails");

    ok(afsconf_DeleteUser(dir, "notthere") != 0,
       "Deleting a user that doesn't exist fails");

    /* Delete the normal user */
    ok(afsconf_DeleteUser(dir, "another") == 0,
       "Deleting normal user works");

    ok(!afsconf_IsSuperIdentity(dir, anotherId),
       "Deleted user is no longer super user");

    ok(afsconf_IsSuperIdentity(dir, testId) &&
       afsconf_IsSuperIdentity(dir, extendedId),
       "Other identities still are");

    ok(afsconf_DeleteIdentity(dir, extendedId) == 0,
       "Deleting identity works");

    ok(!afsconf_IsSuperIdentity(dir, extendedId),
       "Deleted identity is no longer special");

    /* Now, what happens if we're doing something over the network instead */

    code = rx_Init(0);
    is_int(code, 0, "Initialised RX");

    /* Fake up an rx ticket. Note that this will be for the magic 'superuser' */
    code = afsconf_ClientAuth(dir, &class, &classIndex);
    is_int(code, 0, "Can successfully create superuser token");

    /* Start a connection to our test service with it */
    he = gethostbyname("localhost");
    if (!he) {
        printf("Couldn't look up server hostname");
        exit(1);
    }

    memcpy(&addr, he->h_addr, sizeof(afs_uint32));

    conn = rx_NewConnection(addr, htons(TEST_PORT), TEST_SERVICE_ID,
			    class, classIndex);

    /* There's nothing in the list, so this just succeeds because we can */
    code = TEST_CanI(conn, &result);
    is_int(0, code, "Can run a simple RPC");

    code = TEST_WhoAmI(conn, &string);
    is_int(0, code, "Can get identity back");
    is_string("<LocalAuth>", string, "Forged token is super user");

    xdr_free((xdrproc_t)xdr_string, &string);

    /* Throw away this connection and security class */
    rx_DestroyConnection(conn);
    rxs_Release(class);

    /* Now fake an rx ticket for a normal user. We have to do more work by hand
     * here, sadly */

    startTime = time(NULL);
    class = afstest_FakeRxkadClass(dir, "rpctest", "", "", startTime,
				   startTime + 60* 60);

    conn = rx_NewConnection(addr, htons(TEST_PORT), TEST_SERVICE_ID, class,
			    RX_SECIDX_KAD);

    code = TEST_CanI(conn, &result);
    is_int(EPERM, code,
	   "Running RPC as non-super user fails as expected");
    code = TEST_NewCanI(conn, &result);
    is_int(EPERM, code,
	   "Running new interface RPC as non-super user fails as expected");
    code = TEST_WhoAmI(conn, &string);
    xdr_free((xdrproc_t)xdr_string, &string);
    is_int(EPERM, code,
	   "Running RPC returning string fails as expected");
    code = TEST_NewWhoAmI(conn, &string);
    xdr_free((xdrproc_t)xdr_string, &string);
    is_int(EPERM, code,
	   "Running new interface RPC returning string fails as expected");
    ok(afsconf_AddUser(dir, "rpctest") == 0,
       "Adding %s user works", "rpctest");
    code = TEST_CanI(conn, &result);
    is_int(0, code, "Running RPC as rpctest works");
    code = TEST_NewCanI(conn, &result);
    is_int(0, code, "Running new interface RPC as rpctest works");
    code = TEST_WhoAmI(conn, &string);
    is_int(0, code, "Running RPC returning string as %s works", "rpctest");
    is_string("rpctest", string, "Returned user string matches");
    xdr_free((xdrproc_t)xdr_string, &string);
    code = TEST_NewWhoAmI(conn, &string);
    is_int(0, code, "Running new RPC returning string as %s works", "rpctest");
    is_string("rpctest", string, "Returned user string for new interface matches");
    xdr_free((xdrproc_t)xdr_string, &string);
    rx_DestroyConnection(conn);
    rxs_Release(class);

    /* Now try with an admin principal */
    startTime = time(NULL);
    class = afstest_FakeRxkadClass(dir, "rpctest", "admin", "", startTime,
				   startTime + 60* 60);

    conn = rx_NewConnection(addr, htons(TEST_PORT), TEST_SERVICE_ID, class,
			    RX_SECIDX_KAD);

    code = TEST_CanI(conn, &result);
    is_int(EPERM, code,
	   "Running RPC as non-super user fails as expected");
    code = TEST_NewCanI(conn, &result);
    is_int(EPERM, code,
	   "Running new interface RPC as non-super user fails as expected");
    code = TEST_WhoAmI(conn, &string);
    xdr_free((xdrproc_t)xdr_string, &string);
    is_int(EPERM, code,
	   "Running RPC returning string fails as expected");
    code = TEST_NewWhoAmI(conn, &string);
    xdr_free((xdrproc_t)xdr_string, &string);
    is_int(EPERM, code,
	   "Running new interface RPC returning string fails as expected");

    ok(afsconf_AddUser(dir, "rpctest.admin") == 0,
       "Adding %s user works", "rpctest.admin");

    code = TEST_CanI(conn, &result);
    is_int(0, code, "Running RPC as %s works", "rpctest/admin");
    code = TEST_NewCanI(conn, &result);
    is_int(0, code, "Running new interface RPC as %s works", "rpctest/admin");
    code = TEST_WhoAmI(conn, &string);
    is_int(0, code, "Running RPC returning string as %s works", "rpctest/admin");
    is_string("rpctest.admin", string, "Returned user string matches");
    xdr_free((xdrproc_t)xdr_string, &string);
    code = TEST_NewWhoAmI(conn, &string);
    is_int(0, code, "Running new interface RPC returning string as %s works",
	   "rpctest/admin");
    is_string("rpctest.admin", string,
	      "Returned user string from new interface matches");
    xdr_free((xdrproc_t)xdr_string, &string);

    rx_DestroyConnection(conn);
    rxs_Release(class);
}
Ejemplo n.º 6
0
int
xstat_fs_Init(int a_numServers, struct sockaddr_in *a_socketArray,
	      int a_ProbeFreqInSecs, int (*a_ProbeHandler) (void), int a_flags,
	      int a_numCollections, afs_int32 * a_collIDP)
{
    static char rn[] = "xstat_fs_Init";	/*Routine name */
    afs_int32 code;	/*Return value */
    static struct rx_securityClass *CBsecobj;	/*Callback security object */
    struct rx_securityClass *secobj;	/*Client security object */
    struct rx_service *rxsrv_afsserver;	/*Server for AFS */
    int arg_errfound;		/*Argument error found? */
    int curr_srv;		/*Current server idx */
    struct xstat_fs_ConnectionInfo *curr_conn;	/*Ptr to current conn */
    char *hostNameFound;	/*Ptr to returned host name */
    int conn_err;		/*Connection error? */
    int collIDBytes;		/*Num bytes in coll ID array */
    char hoststr[16];

    /*
     * If we've already been called, snicker at the bozo, gently
     * remind him of his doubtful heritage, and return success.
     */
    if (xstat_fs_initflag) {
	fprintf(stderr, "[%s] Called multiple times!\n", rn);
	return (0);
    } else
	xstat_fs_initflag = 1;

    /*
     * Check the parameters for bogosities.
     */
    arg_errfound = 0;
    if (a_numServers <= 0) {
	fprintf(stderr, "[%s] Illegal number of servers: %d\n", rn,
		a_numServers);
	arg_errfound = 1;
    }
    if (a_socketArray == (struct sockaddr_in *)0) {
	fprintf(stderr, "[%s] Null server socket array argument\n", rn);
	arg_errfound = 1;
    }
    if (a_ProbeFreqInSecs <= 0) {
	fprintf(stderr, "[%s] Illegal probe frequency: %d\n", rn,
		a_ProbeFreqInSecs);
	arg_errfound = 1;
    }
    if (a_ProbeHandler == (int (*)())0) {
	fprintf(stderr, "[%s] Null probe handler function argument\n", rn);
	arg_errfound = 1;
    }
    if (a_numCollections <= 0) {
	fprintf(stderr, "[%s] Illegal collection count argument: %d\n", rn,
		a_numServers);
	arg_errfound = 1;
    }
    if (a_collIDP == NULL) {
	fprintf(stderr, "[%s] Null collection ID array argument\n", rn);
	arg_errfound = 1;
    }
    if (arg_errfound)
	return (-1);

    /*
     * Record our passed-in info.
     */
    xstat_fs_debug = (a_flags & XSTAT_FS_INITFLAG_DEBUGGING);
    xstat_fs_oneShot = (a_flags & XSTAT_FS_INITFLAG_ONE_SHOT);
    xstat_fs_numServers = a_numServers;
    xstat_fs_Handler = a_ProbeHandler;
    xstat_fs_ProbeFreqInSecs = a_ProbeFreqInSecs;
    xstat_fs_numCollections = a_numCollections;
    collIDBytes = xstat_fs_numCollections * sizeof(afs_int32);
    xstat_fs_collIDP = malloc(collIDBytes);
    memcpy(xstat_fs_collIDP, a_collIDP, collIDBytes);
    if (xstat_fs_debug) {
	printf("[%s] Asking for %d collection(s): ", rn,
	       xstat_fs_numCollections);
	for (curr_srv = 0; curr_srv < xstat_fs_numCollections; curr_srv++)
	    printf("%d ", *(xstat_fs_collIDP + curr_srv));
	printf("\n");
    }

    /*
     * Get ready in case we have to do a cleanup - basically, zero
     * everything out.
     */
    code = xstat_fs_CleanupInit();
    if (code)
	return (code);

    /*
     * Allocate the necessary data structures and initialize everything
     * else.
     */
    xstat_fs_ConnInfo = malloc(a_numServers
			       * sizeof(struct xstat_fs_ConnectionInfo));
    if (xstat_fs_ConnInfo == (struct xstat_fs_ConnectionInfo *)0) {
	fprintf(stderr,
		"[%s] Can't allocate %d connection info structs (%" AFS_SIZET_FMT " bytes)\n",
		rn, a_numServers,
		(a_numServers * sizeof(struct xstat_fs_ConnectionInfo)));
	return (-1);		/*No cleanup needs to be done yet */
    }

    /*
     * Initialize the Rx subsystem, just in case nobody's done it.
     */
    if (xstat_fs_debug)
	printf("[%s] Initializing Rx\n", rn);
    code = rx_Init(0);
    if (code) {
	fprintf(stderr, "[%s] Fatal error in rx_Init()\n", rn);
	return (-1);
    }
    if (xstat_fs_debug)
	printf("[%s] Rx initialized\n", rn);

    /*
     * Create a null Rx server security object, to be used by the
     * Callback listener.
     */
    CBsecobj = (struct rx_securityClass *)
	rxnull_NewServerSecurityObject();
    if (CBsecobj == (struct rx_securityClass *)0) {
	fprintf(stderr,
		"[%s] Can't create callback listener's security object.\n",
		rn);
	xstat_fs_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    }
    if (xstat_fs_debug)
	printf("[%s] Callback server security object created\n", rn);

    /*
     * Create a null Rx client security object, to be used by the
     * probe LWP.
     */
    secobj = rxnull_NewClientSecurityObject();
    if (secobj == (struct rx_securityClass *)0) {
	fprintf(stderr,
		"[%s] Can't create probe LWP client security object.\n", rn);
	xstat_fs_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    }
    if (xstat_fs_debug)
	printf("[%s] Probe LWP client security object created\n", rn);

    curr_conn = xstat_fs_ConnInfo;
    conn_err = 0;
    for (curr_srv = 0; curr_srv < a_numServers; curr_srv++) {
	/*
	 * Copy in the socket info for the current server, resolve its
	 * printable name if possible.
	 */
	if (xstat_fs_debug) {
	    char hoststr[16];
	    printf("[%s] Copying in the following socket info:\n", rn);
	    printf("[%s] IP addr %s, port %d\n", rn,
		   afs_inet_ntoa_r((a_socketArray + curr_srv)->sin_addr.s_addr,hoststr),
		   ntohs((a_socketArray + curr_srv)->sin_port));
	}
	memcpy(&(curr_conn->skt), a_socketArray + curr_srv,
	       sizeof(struct sockaddr_in));

	hostNameFound =
	    hostutil_GetNameByINet(curr_conn->skt.sin_addr.s_addr);
	if (hostNameFound == NULL) {
	    fprintf(stderr,
		    "[%s] Can't map Internet address %s to a string name\n",
		    rn, afs_inet_ntoa_r(curr_conn->skt.sin_addr.s_addr,hoststr));
	    curr_conn->hostName[0] = '\0';
	} else {
	    strcpy(curr_conn->hostName, hostNameFound);
	    if (xstat_fs_debug)
		printf("[%s] Host name for server index %d is %s\n", rn,
		       curr_srv, curr_conn->hostName);
	}

	/*
	 * Make an Rx connection to the current server.
	 */
	if (xstat_fs_debug)
	    printf
		("[%s] Connecting to srv idx %d, IP addr %s, port %d, service 1\n",
		 rn, curr_srv, afs_inet_ntoa_r(curr_conn->skt.sin_addr.s_addr,hoststr),
		 ntohs(curr_conn->skt.sin_port));

	curr_conn->rxconn = rx_NewConnection(curr_conn->skt.sin_addr.s_addr,	/*Server addr */
					     curr_conn->skt.sin_port,	/*Server port */
					     1,	/*AFS service # */
					     secobj,	/*Security obj */
					     0);	/*# of above */
	if (curr_conn->rxconn == (struct rx_connection *)0) {
	    fprintf(stderr,
		    "[%s] Can't create Rx connection to server '%s' (%s)\n",
		    rn, curr_conn->hostName, afs_inet_ntoa_r(curr_conn->skt.sin_addr.s_addr,hoststr));
	    conn_err = 1;
	}
	if (xstat_fs_debug)
	    printf("[%s] New connection at %" AFS_PTR_FMT "\n", rn, curr_conn->rxconn);

	/*
	 * Bump the current xstat_fs connection to set up.
	 */
	curr_conn++;

    }				/*for curr_srv */

    /*
     * Create the AFS callback service (listener).
     */
    if (xstat_fs_debug)
	printf("[%s] Creating AFS callback listener\n", rn);
    rxsrv_afsserver = rx_NewService(0,	/*Use default port */
				    1,	/*Service ID */
				    "afs",	/*Service name */
				    &CBsecobj,	/*Ptr to security object(s) */
				    1,	/*# of security objects */
				    RXAFSCB_ExecuteRequest);	/*Dispatcher */
    if (rxsrv_afsserver == (struct rx_service *)0) {
	fprintf(stderr, "[%s] Can't create callback Rx service/listener\n",
		rn);
	xstat_fs_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (-1);
    }
    if (xstat_fs_debug)
	printf("[%s] Callback listener created\n", rn);

    /*
     * Start up the AFS callback service.
     */
    if (xstat_fs_debug)
	printf("[%s] Starting up callback listener.\n", rn);
    rx_StartServer(0);		/*Don't donate yourself to LWP pool */

    /*
     * Start up the probe LWP.
     */
    if (xstat_fs_debug)
	printf("[%s] Creating the probe LWP\n", rn);
    code = LWP_CreateProcess(xstat_fs_LWP,	/*Function to start up */
			     LWP_STACK_SIZE,	/*Stack size in bytes */
			     1,	/*Priority */
			     (void *)0,	/*Parameters */
			     "xstat_fs Worker",	/*Name to use */
			     &probeLWP_ID);	/*Returned LWP process ID */
    if (code) {
	fprintf(stderr, "[%s] Can't create xstat_fs LWP!  Error is %d\n", rn,
		code);
	xstat_fs_Cleanup(1);	/*Delete already-malloc'ed areas */
	return (code);
    }
    if (xstat_fs_debug)
	printf("[%s] Probe LWP process structure located at %" AFS_PTR_FMT "\n", rn,
	       probeLWP_ID);

    /*
     * Return the final results.
     */
    if (conn_err)
	return (-2);
    else
	return (0);
}
Ejemplo n.º 7
0
afs_uint32
xfon_voldump(XFILE * X, int flag, char *name)
{
    struct hostent *he;
    struct rx_securityClass *class;
    struct rx_connection *conn;
    struct ktc_principal sname;
    struct ktc_token token;
    struct afsconf_dir *confdir;
    afs_uint32 code, server_addr;
    afs_int32 volid, partid, date;
    int isnum, index;
    char *x, *y;

    /* Parse out the optional date and server location */
    if (code = rx_Init(0))
	return code;
    if (!(name = strdup(name)))
	return ENOMEM;
    if (x = strrchr(name, ',')) {
	*x++ = 0;
	date = atoi(x);
    } else {
	date = 0;
    }
    if (x = strrchr(name, '@')) {
	int a, b, c, d;

	*x++ = 0;
	if (!(y = strchr(x, '/'))) {
	    free(name);
	    return VL_BADPARTITION;
	}
	*y++ = 0;
	if (sscanf(x, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && a >= 0
	    && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0
	    && d <= 255) {
	    server_addr = (a << 24) | (b << 16) | (c << 8) | d;
	    server_addr = htonl(server_addr);
	} else {
	    he = gethostbyname(x);
	    if (!he) {
		free(name);
		return VL_BADSERVER;
	    }
	    memcpy(&server_addr, he->h_addr, sizeof(server_addr));
	}
	partid = volutil_GetPartitionID(y);
	if (partid < 0) {
	    free(name);
	    return VL_BADPARTITION;
	}
    }

    /* Get tokens and set up a security object */
    confdir = afsconf_Open(AFSCONF_CLIENTNAME);
    if (!confdir) {
	free(name);
	return AFSCONF_NODB;
    }
    if (code = afsconf_GetLocalCell(confdir, sname.cell, MAXKTCNAMELEN)) {
	free(name);
	return code;
    }
    afsconf_Close(confdir);
    strcpy(sname.name, "afs");
    sname.instance[0] = 0;
    code = ktc_GetToken(&sname, &token, sizeof(token), 0);
    if (code) {
	class = rxnull_NewClientSecurityObject();
	index = 0;
    } else {
Ejemplo n.º 8
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 = 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;
    char cellstr[64];
    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 (!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;
    }

    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 = NULL;
        }
	pruclient = NULL;
        refresh = 1;
    }

    if (refresh) {
	strncpy(tconfDir, confDir, sizeof(tconfDir));
        strncpy(tcell, cell, sizeof(tcell));

        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;
	}

	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) {
	/* 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;
}
Ejemplo n.º 9
0
static int
backupInit(void)
{
    afs_int32 code;
    static int initd = 0;	/* ever called? */
    PROCESS watcherPid;
    PROCESS pid;		/* LWP process ID */

    /* Initialization */
    initialize_CMD_error_table();

    /* don't run more than once */
    if (initd) {
	afs_com_err(whoami, 0, "Backup already initialized.");
	return 0;
    }
    initd = 1;

    code = bc_InitConfig((char *)DefaultConfDir);
    if (code) {
	afs_com_err(whoami, code,
		"Can't initialize from config files in directory '%s'",
		DefaultConfDir);
	return (code);
    }

    /*
     * Set up Rx.
     */
    code = LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &pid);
    if (code) {
	afs_com_err(whoami, code, "; Can't initialize LWP");
	return (code);
    }

    code = rx_Init(htons(0));
    if (code) {
	afs_com_err(whoami, code, "; Can't initialize Rx");
	return (code);
    }

    rx_SetRxDeadTime(60);

    /* VLDB initialization */
    code = vldbClientInit(0, localauth, tcell, &cstruct, &tokenExpires);
    if (code)
	return (code);

    /* Backup database initialization */
    code = udbClientInit(0, localauth, tcell);
    if (code)
	return (code);

    /* setup status monitoring thread */
    initStatus();
    code =
	LWP_CreateProcess(statusWatcher, 20480, LWP_NORMAL_PRIORITY,
			  (void *)2, "statusWatcher", &watcherPid);
    if (code) {
	afs_com_err(whoami, code, "; Can't create status monitor task");
	return (code);
    }

    return (0);
}
Ejemplo n.º 10
0
void
afspag_Init(afs_int32 nfs_server_addr)
{
    struct clientcred ccred;
    struct rmtbulk idata, odata;
    afs_int32 code, err, addr, obuf;
    int i;

    afs_uuid_create(&afs_cb_interface.uuid);

    AFS_GLOCK();

    afs_InitStats();
    rx_Init(htons(7001));

    AFS_STATCNT(afs_ResourceInit);
    AFS_RWLOCK_INIT(&afs_xuser, "afs_xuser");
    AFS_RWLOCK_INIT(&afs_xpagcell, "afs_xpagcell");
    AFS_RWLOCK_INIT(&afs_xpagsys, "afs_xpagsys");
    AFS_RWLOCK_INIT(&afs_icl_lock, "afs_icl_lock");

    afs_resourceinit_flag = 1;
    afs_nfs_server_addr = nfs_server_addr;
    for (i = 0; i < MAXNUMSYSNAMES; i++) {
	afs_sysnamelist[i] = afs_osi_Alloc(MAXSYSNAME);
        osi_Assert(afs_sysnamelist[i] != NULL);
    }
    afs_sysname = afs_sysnamelist[0];
    strcpy(afs_sysname, SYS_NAME);
    afs_sysnamecount = 1;
    afs_sysnamegen++;

    srv_secobj = rxnull_NewServerSecurityObject();
    stats_svc = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", &srv_secobj,
			      1, RXSTATS_ExecuteRequest);
    pagcb_svc = rx_NewService(0, PAGCB_SERVICEID, "pagcb", &srv_secobj,
			      1, PAGCB_ExecuteRequest);
    rx_StartServer(0);

    clt_secobj = rxnull_NewClientSecurityObject();
    rmtsys_conn = rx_NewConnection(nfs_server_addr, htons(7009),
				   RMTSYS_SERVICEID, clt_secobj, 0);

#ifdef RXK_LISTENER_ENV
    afs_start_thread(rxk_Listener,       "Rx Listener");
#endif
    afs_start_thread((void *)(void *)rx_ServerProc,      "Rx Server Thread");
    afs_start_thread(afs_rxevent_daemon, "Rx Event Daemon");
    afs_start_thread(afs_Daemon,         "AFS PAG Daemon");

    afs_icl_InitLogs();

    AFS_GUNLOCK();

    /* If it's reachable, tell the translator to nuke our creds.
     * We should be more agressive about making sure this gets done,
     * even if the translator is unreachable when we boot.
     */
    addr = obuf = err = 0;
    idata.rmtbulk_len = sizeof(addr);
    idata.rmtbulk_val = (char *)&addr;
    odata.rmtbulk_len = sizeof(obuf);
    odata.rmtbulk_val = (char *)&obuf;
    memset(&ccred, 0, sizeof(ccred));
    code = RMTSYS_Pioctl(rmtsys_conn, &ccred, NIL_PATHP, 0x4F01, 0,
                         &idata, &odata, &err);
}				/*afs_ResourceInit */
Ejemplo n.º 11
0
static int
internal_client_init(struct afsconf_dir *dir, struct afsconf_cell *info,
		     int secFlags, struct ubik_client **uclientp,
		     int (*secproc) (struct rx_securityClass *, afs_int32),
		     int maxservers, const char *serviceid, int deadtime,
		     afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
{
    int code, i;
    afs_int32 scIndex;
    struct rx_securityClass *sc;
    /* This must change if VLDB_MAXSERVERS becomes larger than MAXSERVERS */
    static struct rx_connection *serverconns[MAXSERVERS];
    const char *progname;

    progname = getprogname();
    if (progname == NULL)
	progname = "<unknown>";

    code = rx_Init(0);
    if (code) {
	fprintf(stderr, "%s: could not initialize rx.\n", progname);
	return code;
    }
    rx_SetRxDeadTime(deadtime);

    code = afsconf_PickClientSecObj(dir, secFlags, info, NULL, &sc,
				    &scIndex, NULL);
    if (code) {
	fprintf(stderr, "%s: can't create client security object", progname);
	return code;
    }

    if (scIndex == RX_SECIDX_NULL && !(secFlags & AFSCONF_SECOPTS_NOAUTH)) {
	fprintf(stderr,
		"%s: Could not get afs tokens, running unauthenticated.\n",
		progname);
    }

    if (secproc)	/* tell UV module about default authentication */
	(*secproc) (sc, scIndex);

    if (server) {
	serverconns[0] = rx_NewConnection(server, port,
					  usrvid, sc, scIndex);
    } else {
	if (info->numServers > maxservers) {
	    fprintf(stderr,
		    "%s: info.numServers=%d (> maxservers=%d)\n",
		    progname, info->numServers, maxservers);
	    return -1;
	}
	for (i = 0; i < info->numServers; i++) {
	    if (!info->hostAddr[i].sin_port && port)
		info->hostAddr[i].sin_port = port;
	    serverconns[i] =
		rx_NewConnection(info->hostAddr[i].sin_addr.s_addr,
				 info->hostAddr[i].sin_port, usrvid,
				 sc, scIndex);
	}
    }
    /* Are we just setting up connections, or is this really ubik stuff? */
    if (uclientp) {
	*uclientp = 0;
	code = ubik_ClientInit(serverconns, uclientp);
	if (code)
	    fprintf(stderr, "%s: ubik client init failed.\n", progname);
	    return code;
    }

    return 0;
}
Ejemplo n.º 12
0
int
CommandProc(struct cmd_syndesc *as, void *arock)
{
    char name[MAXKTCNAMELEN] = "";
    char instance[MAXKTCNAMELEN] = "";
    char cell[MAXKTCREALMLEN] = "";
    char realm[MAXKTCREALMLEN] = "";
    afs_int32 serverList[MAXSERVERS];
    char *lcell;		/* local cellname */
    int code;
    int i;

    struct ubik_client *conn = 0;
    struct ktc_encryptionKey key;
    struct ktc_encryptionKey mitkey;
    struct ktc_encryptionKey newkey;
    struct ktc_encryptionKey newmitkey;

    struct ktc_token token;

    struct passwd pwent;
    struct passwd *pw = &pwent;

    int insist;			/* insist on good password quality */
    int lexplicit = 0;		/* servers specified explicitly */
    int local;			/* explicit cell is same a local cell */
    int foundPassword = 0;	/*Not yet, anyway */
    int foundNewPassword = 0;	/*Not yet, anyway */
    int foundExplicitCell = 0;	/*Not yet, anyway */
#ifdef DEFAULT_MITV4_STRINGTOKEY
    int dess2k = 1;
#elif DEFAULT_AFS_STRINGTOKEY
    int dess2k = 0;
#else
    int dess2k = -1;
#endif

    /* blow away command line arguments */
    for (i = 1; i < zero_argc; i++)
	memset(zero_argv[i], 0, strlen(zero_argv[i]));
    zero_argc = 0;

    /* first determine quiet flag based on -pipe switch */
    Pipe = (as->parms[aPIPE].items ? 1 : 0);

#if TIMEOUT
    signal(SIGALRM, timedout);
    alarm(30);
#endif

    code = ka_Init(0);
    if (code || !(lcell = ka_LocalCell())) {
#ifndef AFS_FREELANCE_CLIENT
	if (!Pipe)
	    afs_com_err(rn, code, "Can't get local cell name!");
	exit(1);
#endif
    }

    code = rx_Init(0);
    if (code) {
	if (!Pipe)
	    afs_com_err(rn, code, "Failed to initialize Rx");
	exit(1);
    }

    strcpy(instance, "");

    /* Parse our arguments. */

    if (as->parms[aCELL].items) {
	/*
	 * cell name explicitly mentioned; take it in if no other cell name
	 * has already been specified and if the name actually appears.  If
	 * the given cell name differs from our own, we don't do a lookup.
	 */
	foundExplicitCell = 1;
	strncpy(realm, as->parms[aCELL].items->data, sizeof(realm));
    }

    if (as->parms[aSERVERS].items) {
	/* explicit server list */
	int i;
	struct cmd_item *ip;
	char *ap[MAXSERVERS + 2];

	for (ip = as->parms[aSERVERS].items, i = 2; ip; ip = ip->next, i++)
	    ap[i] = ip->data;
	ap[0] = "";
	ap[1] = "-servers";
	code = ubik_ParseClientList(i, ap, serverList);
	if (code) {
	    if (!Pipe)
		afs_com_err(rn, code, "could not parse server list");
	    return code;
	}
	lexplicit = 1;
    }

    if (as->parms[aPRINCIPAL].items) {
	ka_ParseLoginName(as->parms[aPRINCIPAL].items->data, name, instance,
			  cell);
	if (strlen(instance) > 0)
	    if (!Pipe)
		fprintf(stderr,
			"Non-null instance (%s) may cause strange behavior.\n",
			instance);
	if (strlen(cell) > 0) {
	    if (foundExplicitCell) {
		if (!Pipe)
		    fprintf(stderr,
			    "%s: May not specify an explicit cell twice.\n",
			    rn);
		return -1;
	    }
	    foundExplicitCell = 1;
	    strncpy(realm, cell, sizeof(realm));
	}
	pw->pw_name = name;
    } else {
	/* No explicit name provided: use Unix uid. */
#ifdef AFS_NT40_ENV
	userNameLen = 128;
	if (GetUserName(userName, &userNameLen) == 0) {
	    if (!Pipe) {
		fprintf(stderr,
			"Can't figure out your name in local cell %s from your user id.\n",
			lcell);
		fprintf(stderr, "Try providing the user name.\n");
	    }
	    exit(1);
	}
	pw->pw_name = userName;
#else
	pw = getpwuid(getuid());
	if (pw == 0) {
	    if (!Pipe) {
		fprintf(stderr,
			"Can't figure out your name in local cell %s from your user id.\n",
			lcell);
		fprintf(stderr, "Try providing the user name.\n");
	    }
	    exit(1);
	}
#endif
    }

    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!
	 */
	foundPassword = 1;
	strncpy(passwd, as->parms[aPASSWORD].items->data, sizeof(passwd));
	memset(as->parms[aPASSWORD].items->data, 0,
	       strlen(as->parms[aPASSWORD].items->data));
    }

    if (as->parms[aNEWPASSWORD].items) {
	/*
	 * Current argument is the new password string.  Remember it in
	 * our local buffer, and zero out the argument string - anyone can
	 * see it there with ps!
	 */
	foundNewPassword = 1;
	strncpy(npasswd, as->parms[aNEWPASSWORD].items->data,
		sizeof(npasswd));
	memset(as->parms[aNEWPASSWORD].items->data, 0,
	       strlen(as->parms[aNEWPASSWORD].items->data));
    }
#ifdef AFS_FREELANCE_CLIENT
    if (!foundExplicitCell && !lcell) {
	if (!Pipe)
	    afs_com_err(rn, code, "no cell name provided");
	exit(1);
    }
#else
    if (!foundExplicitCell)
	strcpy(realm, lcell);
#endif /* freelance */

    if ((code = ka_CellToRealm(realm, realm, &local))) {
	if (!Pipe)
	    afs_com_err(rn, code, "Can't convert cell to realm");
	exit(1);
    }
    lcstring(cell, realm, sizeof(cell));

    ka_PrintUserID("Changing password for '", pw->pw_name, instance, "'");
    printf(" in cell '%s'.\n", cell);

    /* Get the password if it wasn't provided. */
    if (!foundPassword) {
	if (Pipe)
	    getpipepass(passwd, sizeof(passwd));
	else {
	    code = read_pass(passwd, sizeof(passwd), "Old password: "******"reading password");
		exit(1);
	    }
	}
    }
    ka_StringToKey(passwd, realm, &key);
    des_string_to_key(passwd, ktc_to_cblockptr(&mitkey));
    give_to_child(passwd);

    /* Get new password if it wasn't provided. */
    insist = 0;
    if (!foundNewPassword) {
	if (Pipe)
	    getpipepass(npasswd, sizeof(npasswd));
	else {
	    do {
		code =
		    read_pass(npasswd, sizeof(npasswd),
			      "New password (RETURN to abort): ", 0);
		if (code || (strlen(npasswd) == 0)) {
		    if (code)
			code = KAREADPW;
		    goto no_change;

		}
	    } while (password_bad(npasswd));

	    code =
		read_pass(verify, sizeof(verify), "Retype new password: "******"Mismatch - ");
		goto no_change;
	    }
	    memset(verify, 0, sizeof(verify));
	}
    }
    if ((code = password_bad(npasswd))) {	/* assmt here! */
	goto no_change_no_msg;
    }
#if TRUNCATEPASSWORD
    if (strlen(npasswd) > 8) {
	npasswd[8] = 0;
	fprintf(stderr,
		"%s: password too long, only the first 8 chars will be used.\n",
		rn);
    } else
	npasswd[8] = 0;		/* in case the password was exactly 8 chars long */
#endif
    ka_StringToKey(npasswd, realm, &newkey);
    des_string_to_key(npasswd, ktc_to_cblockptr(&newmitkey));
    memset(npasswd, 0, sizeof(npasswd));

    if (lexplicit)
	ka_ExplicitCell(realm, serverList);

    /* Get an connection to kaserver's admin service in desired cell.  Set the
     * lifetime above the time uncertainty so that badly skewed clocks are
     * reported when the ticket is decrypted.  Then give us 10 seconds to
     * actually get our work done if the clocks are skewed by only 14:59.
     * NOTE: Kerberos lifetime encoding will round this up to next 5 minute
     * interval, namely 20 minutes. */

#define ADMIN_LIFETIME (KTC_TIME_UNCERTAINTY+1)

    code =
	ka_GetAdminToken(pw->pw_name, instance, realm, &key, ADMIN_LIFETIME,
			 &token, /*!new */ 0);
    if (code == KABADREQUEST) {
	code =
	    ka_GetAdminToken(pw->pw_name, instance, realm, &mitkey,
			     ADMIN_LIFETIME, &token, /*!new */ 0);
	if ((code == KABADREQUEST) && (strlen(passwd) > 8)) {
	    /* try with only the first 8 characters incase they set their password
	     * with an old style passwd program. */
	    char pass8[9];
	    strncpy(pass8, passwd, 8);
	    pass8[8] = 0;
	    ka_StringToKey(pass8, realm, &key);
	    memset(pass8, 0, sizeof(pass8));
	    memset(passwd, 0, sizeof(passwd));
	    code = ka_GetAdminToken(pw->pw_name, instance, realm, &key, ADMIN_LIFETIME, &token,	/*!new */
				    0);
#ifdef notdef
	    /* the folks in testing really *hate* this message */
	    if (code == 0) {
		fprintf(stderr,
			"Warning: only the first 8 characters of your old password were significant.\n");
	    }
#endif
	    if (code == 0) {
		if (dess2k == -1)
		    dess2k = 0;
	    }
	} else {
	    if (dess2k == -1)
		dess2k = 1;
	}
    } else {
	if (dess2k == -1)
	    dess2k = 0;
    }

    memset(&mitkey, 0, sizeof(mitkey));
    memset(&key, 0, sizeof(key));
    if (code == KAUBIKCALL)
	afs_com_err(rn, code, "(Authentication Server unavailable, try later)");
    else if (code) {
	if (code == KABADREQUEST)
	    fprintf(stderr, "%s: Incorrect old password.\n", rn);
	else
	    afs_com_err(rn, code, "so couldn't change password");
    } else {
	code =
	    ka_AuthServerConn(realm, KA_MAINTENANCE_SERVICE, &token, &conn);
	if (code)
	    afs_com_err(rn, code, "contacting Admin Server");
	else {
	    if (dess2k == 1)
		code =
		    ka_ChangePassword(pw->pw_name, instance, conn, 0,
				      &newmitkey);
	    else
		code =
		    ka_ChangePassword(pw->pw_name, instance, conn, 0,
				      &newkey);
	    memset(&newkey, 0, sizeof(newkey));
	    memset(&newmitkey, 0, sizeof(newmitkey));
	    if (code) {
		char *reason;
		reason = (char *)afs_error_message(code);
		fprintf(stderr, "%s: Password was not changed because %s\n",
			rn, reason);
	    } else
		printf("Password changed.\n\n");
	}
    }
    memset(&newkey, 0, sizeof(newkey));
    memset(&newmitkey, 0, sizeof(newmitkey));

    /* Might need to close down the ubik_Client connection */
    if (conn) {
	ubik_ClientDestroy(conn);
	conn = 0;
    }
    rx_Finalize();
    terminate_child();
    exit(code);

  no_change:			/* yuck, yuck, yuck */
    if (code)
	afs_com_err(rn, code, "getting new password");
  no_change_no_msg:
    memset(&key, 0, sizeof(key));
    memset(npasswd, 0, sizeof(npasswd));
    printf("Password for '%s' in cell '%s' unchanged.\n\n", pw->pw_name,
	   cell);
    terminate_child();
    exit(code ? code : 1);
}