Example #1
0
afs_int32
uss_kauth_DelUser(char *a_user)
{				/*uss_kauth_DelUser */
#ifdef USS_KAUTH_DB
    static char rn[] = "uss_kauth_DelUser";	/*Routine name */
#endif
    afs_int32 code;	/*Return code */

    if (uss_SkipKaserver) {
	/*
	 * Don't talk to the kaserver; assume calls succeded and simply return.
	 * Amasingly people want to update it (most likely kerberos) themselves...
	 */
	if (uss_verbose)
	    printf
		("[Skip Kaserver option - Deleting of user %s in Authentication DB not done]\n",
		 a_user);
	return 0;
    }

    /*
     * Make sure the module has been initialized before we start trying
     * to talk to AuthServers.
     */
    if (!initDone) {
	code = InitThisModule();
	if (code)
	    exit(code);
    }

    if (!uss_DryRun) {
#ifdef USS_KAUTH_DB_INSTANCE
	printf("%s: KAM_DeleteUser: user='******', CreatorInstance='%s'\n",
	       uss_whoami, a_user, CreatorInstance);
#endif /* USS_KAUTH_DB_INSTANCE */
	if (uss_verbose)
	    printf("Deleting user '%s' from Authentication DB\n", a_user);
	code = ubik_KAM_DeleteUser(
			 uconn_kauthP,	/*Ubik client connection struct */
			 0,	/*Flags */
			 a_user,	/*User name to delete */
			 UserInstance);	/*set in CheckUserName() */
	if (code) {
	    if (code == KANOENT) {
		if (uss_verbose)
		    printf
			("%s: No entry for user '%s' in Authentication DB\n",
			 uss_whoami, a_user);
		return (0);
	    } else {
		afs_com_err(uss_whoami, code,
			"while deleting entry in Authentication DB\n");
#ifdef USS_KAUTH_DB
		printf("%s: Error code from KAM_DeleteUser: %d\n", rn, code);
#endif /* USS_KAUTH_DB */
		return (code);
	    }
	}			/*KAM_DeleteUser failed */
    } /*Not a dry run */
    else
	printf("\t[Dry run - user '%s' NOT deleted from Authentication DB]\n",
	       a_user);

    return (0);

}				/*uss_kauth_DelUser */
Example #2
0
/*
 * Requires that you already possess a TGT.
 */
afs_int32
ka_GetAFSTicket(char *name, char *instance, char *realm, Date lifetime,
		afs_int32 flags)
{
    afs_int32 code;
    struct ktc_token token;
    struct ktc_principal server, client;

    code = ka_GetServerToken("afs", "", realm, lifetime, &token, /*new */ 1,
			     /*dosetpag */ flags);
    if (code)
	return code;
    if (ktc_OldPioctl()) {
	int local;
	char username[MAXKTCNAMELEN];
	afs_int32 viceId;
	int len;
	char *whoami = "UserAuthenticate: ptserver";

	strcpy(server.name, "afs");
	strcpy(server.instance, "");
	code = ka_ExpandCell(realm, server.cell, &local);
	if (code)
	    return code;
	code = pr_Initialize(0, AFSDIR_CLIENT_ETC_DIRPATH, server.cell);
	if (code) {
	    afs_com_err(whoami, code, "initializing ptserver in cell '%s'",
		    server.cell);
	    return 0;
	}
	len = strlen(name);
	if (instance[0])
	    len += strlen(instance) + 1;
	if (len >= sizeof(username)) {
	    fprintf(stderr, "user's name '%s'.'%s' would be too large\n",
		    name, instance);
	    return 0;
	}
	strcpy(username, name);
	if (instance[0]) {
	    strcat(username, ".");
	    strcat(username, instance);
	}
	code = pr_SNameToId(username, &viceId);
	/* Before going further, shutdown the pr ubik connection */
	pr_End();
	if ((code == 0) && (viceId == ANONYMOUSID))
	    code = PRNOENT;
	if (code) {
	    afs_com_err(whoami, code, "translating %s to id", username);
	    return 0;
	}

	sprintf(client.name, "AFS ID %d", viceId);
	strcpy(client.instance, "");
	strcpy(client.cell, server.cell);
	code = ktc_SetToken(&server, &token, &client, /*dosetpag */ 0);
	if (code)
	    return code;
    }
    return code;
}
Example #3
0
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];
    time_t lifetime;		/* requested ticket lifetime */
    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;
    }

    if (as->parms[aLIFETIME].items) {
	char *life = as->parms[aLIFETIME].items->data;
	char *sp;		/* string ptr to rest of life */
	lifetime = 3600 * strtol(life, &sp, 0);	/* hours */
	if (sp == life) {
	  bad_lifetime:
	    if (!Silent)
		fprintf(stderr, "%s: translating '%s' to lifetime failed\n",
			rn, life);
	    return 1;
	}
	if (*sp == ':') {
	    life = sp + 1;	/* skip the colon */
	    lifetime += 60 * strtol(life, &sp, 0);	/* minutes */
	    if (sp == life)
		goto bad_lifetime;
	    if (*sp == ':') {
		life = sp + 1;
		lifetime += strtol(life, &sp, 0);	/* seconds */
		if (sp == life)
		    goto bad_lifetime;
		if (*sp)
		    goto bad_lifetime;
	    } else if (*sp)
		goto bad_lifetime;
	} else if (*sp)
	    goto bad_lifetime;
    } else
	lifetime = 0;

    /* 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;
}
Example #4
0
int
bc_SetExpCmd(struct cmd_syndesc *as, void *arock)
{
    char *dname;	/* dump schedule name */
    struct cmd_item *ti;
    struct bc_dumpSchedule *node, *parent;
    afs_int32 expType, expDate;
    udbClientTextP ctPtr;
    int code;

    /* if an expiration date has been specified */
    if (as->parms[1].items) {
	code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
	if (code) {
	    printf("Invalid expiration date syntax\n");
	    return (1);
	}
    } else {
	/* no expiration date specified */
	expDate = 0;
	expType = BC_NO_EXPDATE;
    }

    /* lock schedules and check validity */
    ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];

    code = bc_LockText(ctPtr);
    if (code)
	ERROR(code);

    code = bc_UpdateDumpSchedule();
    if (code) {
	afs_com_err(whoami, code, "; Can't retrieve dump schedule");
	return (code);
    }

    /* process each dump name using the expiration date computed above */
    for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
	/* get next dump name to process */
	dname = ti->data;

	/* validate the name dump name length */
	if (strlen(dname) >= BU_MAX_DUMP_PATH) {
	    code = -1;
	    afs_com_err(whoami, 0, "Dump names must be < %d characters",
		    BU_MAX_DUMP_PATH);
	    afs_com_err(whoami, 0, "Dump %s not added", dname);
	    continue;
	}

	code = FindDump(bc_globalConfig, dname, &parent, &node);
	if (code) {
	    afs_com_err(whoami, 0, "Dump level %s not found", dname);
	    continue;
	}

	node->expDate = expDate;
	node->expType = expType;
    }

    code = bc_SaveDumpSchedule();
    if (code) {
	afs_com_err(whoami, code, "Cannot save dump schedule");
	afs_com_err(whoami, 0,
		"Expiration changes effective for this session only");
    }

  error_exit:
    if (ctPtr->lockHandle)
	bc_UnlockText(ctPtr);
    return (code);
}
Example #5
0
int
bc_AddDumpCmd(struct cmd_syndesc *as, void *arock)
{
    char *dname;	/* dump schedule name */
    int code;
    afs_int32 expType, expDate;
    struct cmd_item *ti;
    udbClientTextP ctPtr;

    /* if an expiration date has been specified */
    if (as->parms[1].items) {
	code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
	if (code) {
	    printf("Invalid expiration date syntax\n");
	    return (1);
	}
    } else {
	/* no expiration date specified */
	expDate = 0;
	expType = BC_NO_EXPDATE;
    }

    /* lock schedules and check validity */
    ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];

    code = bc_LockText(ctPtr);
    if (code)
	ERROR(code);

    code = bc_UpdateDumpSchedule();
    if (code) {
	afs_com_err(whoami, code, "; Can't retrieve dump schedule");
	return (code);
    }

    /* process each dump name using the expiration date computed above */
    for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
	/* get next dump name to process */
	dname = ti->data;

	/* validate the name dump name length */
	if (strlen(dname) >= BU_MAX_DUMP_PATH) {
	    afs_com_err(whoami, 0, "Dump names must be < %d characters",
		    BU_MAX_DUMP_PATH);
	    afs_com_err(whoami, 0, "Dump %s not added", dname);
	    code = -1;
	    continue;
	}

	code =
	    bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
	if (code) {
	    if (code == -1)
		afs_com_err(whoami, 0, "Dump already exists");
	    else if (code == -2)
		afs_com_err(whoami, 0, "Invalid path name '%s'", dname);
	    else if (code == -3)
		afs_com_err(whoami, 0, "Name specification error");
	    else
		afs_com_err(whoami, code, "; Failed to create dump schedule");
	    continue;
	}

	/* save the new schedule item */
	code = bc_SaveDumpSchedule();
	if (code) {
	    afs_com_err(whoami, code, "Cannot save dump schedule");
	    afs_com_err(whoami, 0,
		    "Changes are temporary - for this session only");
	    break;
	}

	afs_com_err(whoami, 0, "Created new dump schedule %s", dname);
    }

  error_exit:
    if (ctPtr->lockHandle)
	bc_UnlockText(ctPtr);
    return (code);
}
Example #6
0
long
rxkst_StartClient(struct clientParms *parms)
{
    long code;
    long host;
    long scIndex;
    struct rx_securityClass *sc;

    whoami = parms->whoami;	/* set this global variable */

    host = GetServer(parms->server);

    if (parms->authentication >= 0) {
	long kvno = 0;
	char ticket[MAXKTCTICKETLEN];
	int ticketLen;
	struct ktc_encryptionKey Ksession;

	if (parms->useTokens)
	    code =
		GetToken(&kvno, &Ksession, &ticketLen, ticket, parms->cell);
	else
	    code =
		GetTicket(&kvno, &Ksession, &ticketLen, ticket, parms->cell);
	if (code)
	    return code;

	/* next, we have ticket, kvno and session key, authenticate the conn */
	sc = (struct rx_securityClass *)
	    rxkad_NewClientSecurityObject(parms->authentication, &Ksession,
					  kvno, ticketLen, ticket);
	assert(sc);
	scIndex = RX_SECIDX_KAD;
    } else {
	/* unauthenticated connection */
	sc = rxnull_NewClientSecurityObject();
	assert(sc);
	scIndex = RX_SECIDX_NULL;
    }

    code = 0;
    if (!code && parms->callTest) {
	code = RunCallTest(parms, host, sc, scIndex);
    }
    if (!code && parms->hijackTest) {
	code = RunHijackTest(parms, host, sc, scIndex);
    }
    if (!code
	&& (parms->printTiming || parms->fastCalls || parms->slowCalls
	    || parms->copiousCalls)) {
	struct rx_connection *conn;
	conn =
	    rx_NewConnection(host, htons(RXKST_SERVICEPORT), RXKST_SERVICEID,
			     sc, scIndex);
	if (conn) {
	    code = RepeatLoadTest(parms, conn);
	    rx_DestroyConnection(conn);
	} else
	    code = RXKST_NEWCONNFAILED;
    }
    if (!code && parms->stopServer) {
	struct rx_connection *conn;
	conn =
	    rx_NewConnection(host, htons(RXKST_SERVICEPORT), RXKST_SERVICEID,
			     sc, scIndex);
	if (conn) {
	    code = RXKST_Kill(conn);
	    if (code) {
		afs_com_err(whoami, code, "trying to stop server");
	    }
	    rx_DestroyConnection(conn);
	} else
	    code = RXKST_NEWCONNFAILED;
    }

    if (parms->printStats) {
	rx_PrintStats(stdout);
#if 0
	/* use rxdebug style iteration here */
	rx_PrintPeerStats(stdout, rx_PeerOf(conn));
#endif
    }

    rxs_Release(sc);
    rx_Finalize();
    if (code) {
	afs_com_err(parms->whoami, code, "test fails");
	exit(13);
    } else {
	printf("Test Okay\n");
	if (!parms->noExit)
	    exit(0);
    }
    return 0;
}
Example #7
0
static long
RunLoadTest(struct clientParms *parms, struct rx_connection *conn)
{
    long code;
    struct client c;
    u_long fastCalls[MAX_CTHREADS];
    u_long slowCalls[MAX_CTHREADS];
    u_long copiousCalls[MAX_CTHREADS];
    double start, interval;

    DivideUpCalls(parms->fastCalls, parms->threads, fastCalls);
    DivideUpCalls(parms->slowCalls, parms->threads, slowCalls);
    DivideUpCalls(parms->copiousCalls, parms->threads, copiousCalls);

    memset(&c, 0, sizeof(c));
    c.conn = conn;
    c.sendLen = parms->sendLen;
    c.recvLen = parms->recvLen;
    c.fastCalls = fastCalls;
    c.slowCalls = slowCalls;
    c.copiousCalls = copiousCalls;

    start = ftime();
    code = CallSimultaneously(parms->threads, &c, DoClient);
    if (code) {
	afs_com_err(whoami, code, "in DoClient");
	return code;
    }
    interval = ftime() - start;

    if (parms->printTiming) {
	u_long totalCalls =
	    parms->fastCalls + parms->slowCalls + parms->copiousCalls;
	int t = (interval / totalCalls) * 1000.0 + 0.5;
	if (totalCalls > 0) {
	    printf("For %lu calls: %d msec/call\n", totalCalls, t);
	}
	if (parms->copiousCalls > 0) {
	    long n = parms->sendLen + parms->recvLen;
	    double kbps;
	    int b;
	    kbps = (double)(parms->copiousCalls * n) / (interval * 1000.0);
	    b = kbps + 0.5;
#if 0
	    I just cannot get printing of floats to work on the pmax !
		!!!printf("%g %d %d %d\n", (float)kbps, b);
	    printf("%g %d %d %d\n", kbps, b);
	    fprintf(stdout, "%g %d %d\n", kbps, b);
	    {
		char buf[100];
		buf[sizeof(buf) - 1] = 0;
		sprintf(buf, "%g %d %d\n", kbps, b);
		assert(buf[sizeof(buf) - 1] == 0);
		printf("%s", buf);
	    }
#endif
	    printf
		("For %lu copious calls, %lu send + %lu recv = %lu bytes each: %d kbytes/sec\n",
		 parms->copiousCalls, parms->sendLen, parms->recvLen, n, b);
#if 0
	    printf("%g\n", kbps);
#endif
	}
    }
    return 0;
}
Example #8
0
afs_int32
doDispatch(afs_int32 targc,
	   char *targv[MAXV],
	   afs_int32 dispatchCount) /* to prevent infinite recursion */
{
    char *sargv[MAXV];
    afs_int32 sargc;
    afs_int32 code, c;
    FILE *fd;
    int i;
    int lineNumber;
    int noExecute;		/* local capy of global variable */
    char *internalLoadFile;

    lock_Dispatch();

    loadFile = NULL;
    code = cmd_Dispatch(targc, targv);
    internalLoadFile = loadFile;

    unlock_Dispatch();

    if (internalLoadFile) {	/* Load a file in */
	if (dispatchCount > MAXRECURSION) {	/* Beware recursive loops. */
	    afs_com_err(whoami, 0, "Potential recursion: will not load file %s",
		    internalLoadFile);
	    code = -1;
	    goto done;
	}

	fd = fopen(internalLoadFile, "r");	/* Open the load file */
	if (!fd) {
	    afs_com_err(whoami, errno, "; Cannot open file %s", internalLoadFile);
	    code = -1;
	    goto done;
	}

	noExecute = dontExecute;
	if (noExecute)
	    printf("Would have executed the following commands:\n");

	lineNumber = 0;
	while (fgets(lineBuffer, sizeof(lineBuffer) - 1, fd)) {	/* Get commands from file */
	    lineNumber++;

	    i = strlen(lineBuffer) - 1;
	    if (lineBuffer[i] == '\n')	/* Drop return at end of line */
		lineBuffer[i] = '\0';

	    if (noExecute)
		printf("        %s\n", lineBuffer);	/* echo */
	    else
		printf("------> %s\n", lineBuffer);	/* echo */

	    if (!LineIsBlank(lineBuffer) &&	/* Skip if blank line */
		(lineBuffer[0] != '#') &&	/*      or comment    */
		(!noExecute)) {	/*      or no execute */
		c = cmd_ParseLine(lineBuffer, sargv, &sargc, MAXV);
		if (c) {
		    afs_com_err(whoami, c, "; Can't parse line");
		} else {
		    doDispatch(sargc, sargv, dispatchCount + 1);	/* Recursive - ignore error */
		    cmd_FreeArgv(sargv);	/* Free up arguments */
		}
	    }
	}

	fclose(fd);
    }

  done:
    if (internalLoadFile)
	free(internalLoadFile);
    return (code);
}
Example #9
0
int
main(int argc, char **argv)
{				/*main */
    char *targv[MAXV];		/*Ptr to parsed argv stuff */
    afs_int32 targc;		/*Num parsed arguments */
    afs_int32 code;		/*Return code */
    struct cmd_syndesc *ts;	/*Ptr to parsed command line */
    int i;


#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
    Lock_Init(&dispatchLock);
    InitErrTabs();		/* init all the error tables which may be used */

    /* setup the default backup dir */
    DefaultConfDir = AFSDIR_SERVER_BACKUP_DIRPATH;
    /* Get early warning if the command is interacive mode or not */
    interact = (((argc < 2) || (argv[1][0] == '-')) ? 1 : 0);

    cmd_SetBeforeProc(MyBeforeProc, NULL);

    ts = cmd_CreateSyntax("dump", bc_DumpCmd, NULL, "start dump");
    cmd_AddParm(ts, "-volumeset", CMD_SINGLE, CMD_OPTIONAL,
		"volume set name");
    cmd_AddParm(ts, "-dump", CMD_SINGLE, CMD_OPTIONAL, "dump level name");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    cmd_AddParm(ts, "-at", CMD_LIST, CMD_OPTIONAL, "Date/time to start dump");
    cmd_AddParm(ts, "-append", CMD_FLAG, CMD_OPTIONAL,
		"append to existing dump set");
    cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
                "list what would be done, don't do it");
    cmd_AddParmAlias(ts, 5, "-n");
    cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "load file");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("volrestore", bc_VolRestoreCmd, NULL,
			  "restore volume");
    cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
		"destination machine");
    cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
		"destination partition");
    cmd_AddParm(ts, "-volume", CMD_LIST, CMD_REQUIRED,
		"volume(s) to restore");
    cmd_AddParm(ts, "-extension", CMD_SINGLE, CMD_OPTIONAL,
		"new volume name extension");
    cmd_AddParm(ts, "-date", CMD_LIST, CMD_OPTIONAL,
		"date from which to restore");
    cmd_AddParm(ts, "-portoffset", CMD_LIST, CMD_OPTIONAL, "TC port offsets");
    cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
                "list what would be done, don't do it");
    cmd_AddParmAlias(ts, 6, "-n");
    cmd_AddParm(ts, "-usedump", CMD_SINGLE, CMD_OPTIONAL,
		"specify the dumpID to restore from");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("diskrestore", bc_DiskRestoreCmd, NULL,
			  "restore partition");
    cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
		"machine to restore");
    cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
		"partition to restore");
    cmd_AddParm(ts, "-portoffset", CMD_LIST, CMD_OPTIONAL, "TC port offset");
    cmd_Seek(ts, 8);
    cmd_AddParm(ts, "-newserver", CMD_SINGLE, CMD_OPTIONAL,
		"destination machine");
    cmd_AddParm(ts, "-newpartition", CMD_SINGLE, CMD_OPTIONAL,
		"destination partition");
    cmd_AddParm(ts, "-extension", CMD_SINGLE, CMD_OPTIONAL,
		"new volume name extension");
    cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
                "list what would be done, don't do it");
    cmd_AddParmAlias(ts, 11, "-n");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("quit", bc_QuitCmd, NULL, "leave the program");

    ts = cmd_CreateSyntax("volsetrestore", bc_VolsetRestoreCmd, NULL,
			  "restore a set of volumes");
    cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "volume set name");
    cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "file name");
    cmd_AddParm(ts, "-portoffset", CMD_LIST, CMD_OPTIONAL, "TC port offset");
    cmd_AddParm(ts, "-extension", CMD_SINGLE, CMD_OPTIONAL,
		"new volume name extension");
    cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
                "list what would be done, don't do it");
    cmd_AddParmAlias(ts, 4, "-n");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("addhost", bc_AddHostCmd, NULL, "add host to config");
    cmd_AddParm(ts, "-tapehost", CMD_SINGLE, CMD_REQUIRED,
		"tape machine name");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("delhost", bc_DeleteHostCmd, NULL,
			  "delete host to config");
    cmd_AddParm(ts, "-tapehost", CMD_SINGLE, CMD_REQUIRED,
		"tape machine name");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("listhosts", bc_ListHostsCmd, NULL,
			  "list config hosts");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("jobs", bc_JobsCmd, NULL, "list running jobs");

    ts = cmd_CreateSyntax("kill", bc_KillCmd, NULL, "kill running job");
    cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_REQUIRED,
		"job ID or dump set name");

    ts = cmd_CreateSyntax("listvolsets", bc_ListVolSetCmd, NULL,
			  "list volume sets");
    cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "volume set name");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("listdumps", bc_ListDumpScheduleCmd, NULL,
			  "list dump schedules");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("addvolset", bc_AddVolSetCmd, NULL,
			  "create a new volume set");
    cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED, "volume set name");
    cmd_AddParm(ts, "-temporary", CMD_FLAG, CMD_OPTIONAL,
		"temporary volume set");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("status", bc_GetTapeStatusCmd, NULL,
			  "get tape coordinator status");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("delvolset", bc_DeleteVolSetCmd, NULL,
			  "delete a volume set");
    cmd_AddParm(ts, "-name", CMD_LIST, CMD_REQUIRED, "volume set name");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("addvolentry", bc_AddVolEntryCmd, NULL,
			  "add a new volume entry");
    cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED, "volume set name");
    cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "machine name");
    cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED, "partition name");
    cmd_AddParm(ts, "-volumes", CMD_SINGLE, CMD_REQUIRED,
		"volume name (regular expression)");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("delvolentry", bc_DeleteVolEntryCmd, NULL,
			  "delete a volume set sub-entry");
    cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_REQUIRED, "volume set name");
    cmd_AddParm(ts, "-entry", CMD_SINGLE, CMD_REQUIRED, "volume set index");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("adddump", bc_AddDumpCmd, NULL, "add dump schedule");
    cmd_AddParm(ts, "-dump", CMD_LIST, CMD_REQUIRED, "dump level name");
    cmd_AddParm(ts, "-expires", CMD_LIST, CMD_OPTIONAL, "expiration date");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("deldump", bc_DeleteDumpCmd, NULL,
			  "delete dump schedule");
    cmd_AddParm(ts, "-dump", CMD_SINGLE, CMD_REQUIRED, "dump level name");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("labeltape", bc_LabelTapeCmd, NULL, "label a tape");
    cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL,
		"AFS tape name, defaults to NULL");
    cmd_AddParm(ts, "-size", CMD_SINGLE, CMD_OPTIONAL,
		"tape size in Kbytes, defaults to size in tapeconfig");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    cmd_AddParm(ts, "-pname", CMD_SINGLE, CMD_OPTIONAL,
		"permanent tape name");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("readlabel", bc_ReadLabelCmd, NULL,
			  "read the label on tape");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("scantape", bc_ScanDumpsCmd, NULL,
			  "dump information recovery from tape");
    cmd_AddParm(ts, "-dbadd", CMD_FLAG, CMD_OPTIONAL,
		"add information to the database");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("volinfo", bc_dblookupCmd, NULL,
			  "query the backup database");
    cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume name");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("setexp", bc_SetExpCmd, NULL,
			  "set/clear dump expiration dates");
    cmd_AddParm(ts, "-dump", CMD_LIST, CMD_REQUIRED, "dump level name");
    cmd_AddParm(ts, "-expires", CMD_LIST, CMD_OPTIONAL, "expiration date");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("savedb", bc_saveDbCmd, NULL, "save backup database");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    cmd_AddParm(ts, "-archive", CMD_LIST, CMD_OPTIONAL, "date time");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("restoredb", bc_restoreDbCmd, NULL,
			  "restore backup database");
    cmd_AddParm(ts, "-portoffset", CMD_SINGLE, CMD_OPTIONAL,
		"TC port offset");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("dumpinfo", bc_dumpInfoCmd, NULL,
			  "provide information about a dump in the database");
    cmd_AddParm(ts, "-ndumps", CMD_SINGLE, CMD_OPTIONAL, "no. of dumps");
    cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "dump id");
    cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL,
		"detailed description");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("dbverify", bc_dbVerifyCmd, NULL,
			  "check ubik database integrity");
    cmd_AddParm(ts, "-detail", CMD_FLAG, CMD_OPTIONAL, "additional details");
    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("deletedump", bc_deleteDumpCmd, NULL,
			  "delete dumps from the database");
    cmd_AddParm(ts, "-dumpid", CMD_LIST, CMD_OPTIONAL, "dump id");
    cmd_AddParm(ts, "-from", CMD_LIST, CMD_OPTIONAL, "date time");
    cmd_AddParm(ts, "-to", CMD_LIST, CMD_OPTIONAL, "date time");
    cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "TC port offset");
    cmd_AddParm(ts, "-groupid", CMD_SINGLE, CMD_OPTIONAL, "group ID");
    cmd_AddParm(ts, "-dbonly", CMD_FLAG, CMD_OPTIONAL,
		"delete the dump from the backup database only");
    cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
		"always delete from backup database");
    cmd_AddParm(ts, "-noexecute", CMD_FLAG, CMD_OPTIONAL|CMD_HIDDEN, "");
    cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL,
		"list the dumps, don't delete anything");
    cmd_AddParmAlias(ts, 8, "-n");

    if (!interact)
	add_std_args(ts);

    ts = cmd_CreateSyntax("interactive", bc_interactCmd, NULL,
			  "enter interactive mode");
    add_std_args(ts);

    /*
     * Now execute the command.
     */

    targc = 0;
    targv[targc++] = argv[0];
    if (interact)
	targv[targc++] = "interactive";
    for (i = 1; i < argc; i++)
	targv[targc++] = argv[i];

    code = doDispatch(targc, targv, 1);

    if (!interact || !bcInit) {	/* Non-interactive mode */
	if (code)
	    exit(-1);
	if (bcInit)
	    code = bc_WaitForNoJobs();	/* wait for any jobs to finish */
	exit(code);		/* and exit */
    }

    /* Iterate on command lines, interpreting user commands (interactive mode) */
    while (1) {
	int ret;

	printf("backup> ");
	fflush(stdout);


	while ((ret = LWP_GetLine(lineBuffer, sizeof(lineBuffer))) == 0)
	    printf("%s: Command line too long\n", whoami);	/* line too long */

	if (ret == -1)
	    return 0;		/* Got EOF */

	if (!LineIsBlank(lineBuffer)) {
	    code = cmd_ParseLine(lineBuffer, targv, &targc, MAXV);
	    if (code)
		afs_com_err(whoami, code, "; Can't parse line: '%s'",
			afs_error_message(code));
	    else {
		doDispatch(targc, targv, 1);
		cmd_FreeArgv(targv);
	    }
	}
    }
}				/*main */
Example #10
0
static struct afsconf_typedKey *
keyFromKeytab(int kvno, afsconf_keyType type, int subtype, const char *keytab, const char *princ)
{
    int retval;
    krb5_principal principal;
    krb5_keyblock *key;
    krb5_context context;
    struct rx_opaque buffer;
    struct afsconf_typedKey *typedKey;

    krb5_init_context(&context);

    retval = krb5_parse_name(context, princ, &principal);
    if (retval) {
	afs_com_err("asetkey", retval, "while parsing AFS principal");
	exit(1);
    }

    if (type == afsconf_rxkad) {
	retval = krb5_kt_read_service_key(context, (char *)keytab, principal,
					  kvno, ENCTYPE_DES_CBC_CRC, &key);
	if (retval == KRB5_KT_NOTFOUND)
	    retval = krb5_kt_read_service_key(context, (char *)keytab,
					      principal, kvno,
					      ENCTYPE_DES_CBC_MD5, &key);
	if (retval == KRB5_KT_NOTFOUND)
	    retval = krb5_kt_read_service_key(context, (char *)keytab,
					      principal, kvno,
					      ENCTYPE_DES_CBC_MD4, &key);
    } else if (type == afsconf_rxkad_krb5) {
	retval = krb5_kt_read_service_key(context, (char *)keytab, principal,
					  kvno, subtype, &key);
    } else {
	retval=AFSCONF_BADKEY;
    }
    if (retval == KRB5_KT_NOTFOUND) {
	char * princname = NULL;

	krb5_unparse_name(context, principal, &princname);

	if (type == afsconf_rxkad) {
	    afs_com_err("asetkey", retval,
			"for keytab entry with Principal %s, kvno %u, "
			"DES-CBC-CRC/MD5/MD4",
			princname ? princname : princ, kvno);
	} else {
	    afs_com_err("asetkey", retval,
			"for keytab entry with Principal %s, kvno %u",
			princname ? princname : princ, kvno);
	}
	exit(1);
    }

    if (retval != 0) {
	afs_com_err("asetkey", retval, "while extracting AFS service key");
	exit(1);
    }

    if (type == afsconf_rxkad && deref_key_length(key) != 8) {
	fprintf(stderr, "Key length should be 8, but is really %u!\n",
		(unsigned int)deref_key_length(key));
	exit(1);
    }

    rx_opaque_populate(&buffer, deref_key_contents(key), deref_key_length(key));

    typedKey = afsconf_typedKey_new(type, kvno, subtype, &buffer);
    rx_opaque_freeContents(&buffer);
    krb5_free_principal(context, principal);
    krb5_free_keyblock(context, key);
    return typedKey;
}
Example #11
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);
}
Example #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);
}
Example #13
0
afs_int32
udbClientInit(int noAuthFlag, int localauth, char *cellName)
{
    struct afsconf_cell info;
    struct afsconf_dir *acdir;
    const char *confdir;
    int i;
    afs_int32 secFlags;
    afs_int32 code = 0;

    secFlags = parseSecFlags(noAuthFlag, localauth, &confdir);
    secFlags |= AFSCONF_SECOPTS_FALLBACK_NULL;

    if (cellName && cellName[0] == '\0')
	cellName = NULL;

    acdir = afsconf_Open(confdir);
    if (!acdir) {
	afs_com_err(whoami, 0, "Can't open configuration directory '%s'",
		    confdir);
	ERROR(BC_NOCELLCONFIG);
    }

    code = afsconf_GetCellInfo(acdir, cellName, 0, &info);
    if (code) {
	afs_com_err(whoami, code, "; Can't find cell %s's hosts in %s/%s",
		    cellName, confdir, AFSDIR_CELLSERVDB_FILE);
	ERROR(BC_NOCELLCONFIG);
    }

    code = afsconf_PickClientSecObj(acdir, secFlags, &info, cellName,
				    &udbHandle.uh_secobj,
				    &udbHandle.uh_scIndex, NULL);
    if (code) {
	afs_com_err(whoami, code, "(configuring connection security)");
	ERROR(BC_NOCELLCONFIG);
    }
    if (&udbHandle.uh_scIndex == RX_SECIDX_NULL && !noAuthFlag)
	afs_com_err(whoami, 0, "Can't get tokens - running unauthenticated");

    if (info.numServers > MAXSERVERS) {
	afs_com_err(whoami, 0,
		"Warning: %d BDB servers exist for cell '%s', can only remember the first %d",
		info.numServers, cellName, MAXSERVERS);
	info.numServers = MAXSERVERS;
    }

    /* establish connections to the servers. Check for failed connections? */
    for (i = 0; i < info.numServers; i++) {
	udbHandle.uh_serverConn[i] =
	    rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
			     htons(AFSCONF_BUDBPORT), BUDB_SERVICE,
			     udbHandle.uh_secobj, udbHandle.uh_scIndex);
    }
    udbHandle.uh_serverConn[i] = 0;

    code = ubik_ClientInit(udbHandle.uh_serverConn, &udbHandle.uh_client);
    if (code) {
	afs_com_err(whoami, code,
		"; Can't initialize ubik connection to backup database");
	ERROR(code);
    }

    /* Try to quickly find a good site by setting deadtime low */
    for (i = 0; i < info.numServers; i++)
	rx_SetConnDeadTime(udbHandle.uh_client->conns[i], 1);
    code =
	ubik_BUDB_GetInstanceId(udbHandle.uh_client, 0,
		  &udbHandle.uh_instanceId);

    /* Reset dead time back up to default */
    for (i = 0; i < info.numServers; i++)
	rx_SetConnDeadTime(udbHandle.uh_client->conns[i], 60);

    /* If did not find a site on first quick pass, try again */
    if (code == -1)
	code =
	    ubik_BUDB_GetInstanceId(udbHandle.uh_client, 0,
		      &udbHandle.uh_instanceId);
    if (code) {
	afs_com_err(whoami, code, "; Can't access backup database");
	ERROR(code);
    }

  error_exit:
    if (acdir)
	afsconf_Close(acdir);
    return (code);
}
Example #14
0
afs_int32
uss_kauth_SetFields(char *username, char *expirestring, char *reuse,
		    char *failures, char *lockout)
{
#ifdef USS_KAUTH_DB
    static char rn[] = "uss_kauth_SetFields";
#endif
    afs_int32 code;
    char misc_auth_bytes[4];
    int i;
    afs_int32 flags = 0;
    Date expiration = 0;
    afs_int32 lifetime = 0;
    afs_int32 maxAssociates = -1;
    afs_int32 was_spare = 0;
    char instance = '\0';
    int pwexpiry;
    int nfailures, locktime, hrs, mins;

    if (strlen(username) > uss_UserLen) {
	fprintf(stderr,
		"%s: * User field in add cmd too long (max is %d chars; truncated value is '%s')\n",
		uss_whoami, uss_UserLen, uss_User);
	return (-1);
    }

    strcpy(uss_User, username);
    code = uss_kauth_CheckUserName();
    if (code)
	return (code);

    /*  no point in doing this any sooner than necessary */
    for (i = 0; i < 4; misc_auth_bytes[i++] = 0);

    pwexpiry = atoi(expirestring);
    if (pwexpiry < 0 || pwexpiry > 254) {
	fprintf(stderr, "Password lifetime range must be [0..254] days.\n");
	fprintf(stderr, "Zero represents an unlimited lifetime.\n");
	fprintf(stderr,
		"Continuing with default lifetime == 0 for user %s.\n",
		username);
	pwexpiry = 0;
    }
    misc_auth_bytes[0] = pwexpiry + 1;

    if (!strcmp(reuse, "noreuse")) {
	misc_auth_bytes[1] = KA_NOREUSEPW;
    } else {
	misc_auth_bytes[1] = KA_REUSEPW;
	if (strcmp(reuse, "reuse"))
	  fprintf(stderr, "must specify \"reuse\" or \"noreuse\": \"reuse\" assumed\n");
    }

    nfailures = atoi(failures);
    if (nfailures < 0 || nfailures > 254) {
	fprintf(stderr, "Failure limit must be in [0..254].\n");
	fprintf(stderr, "Zero represents unlimited login attempts.\n");
	fprintf(stderr, "Continuing with limit == 254 for user %s.\n",
		username);
	misc_auth_bytes[2] = 255;
    } else
	misc_auth_bytes[2] = nfailures + 1;

    hrs = 0;
    if (strchr(lockout, ':'))
	sscanf(lockout, "%d:%d", &hrs, &mins);
    else
	sscanf(lockout, "%d", &mins);

    locktime = hrs*60 + mins;
    if (hrs < 0 || hrs > 36 || mins < 0) {
	fprintf(stderr,"Lockout times must be either minutes or hh:mm.\n");
	fprintf(stderr,"Lockout times must be less than 36 hours.\n");
	return KABADCMD;
    } else if (locktime > 36*60) {
	fprintf(stderr, "Lockout times must be either minutes or hh:mm.\n");
	fprintf(stderr, "Lockout times must be less than 36 hours.\n");
	fprintf(stderr, "Continuing with lock time == forever for user %s.\n",
		username);
	misc_auth_bytes[3] = 1;
    } else {
	locktime = (locktime * 60 + 511) >> 9;  /* ceil(l*60/512) */
	misc_auth_bytes[3] = locktime + 1;
    }

    if (uss_SkipKaserver) {
	if (uss_verbose)
	    printf("[Skipping Kaserver as requested]\n");
	return 0;
    }

    /*
     * Make sure the module has been initialized before we start trying
     * to talk to AuthServers.
     */
    if (!initDone) {
	code = InitThisModule();
	if (code)
	    exit(code);
    }

    if (!uss_DryRun) {
	if (uss_verbose)
	    fprintf(stderr, "Setting options for '%s' in database.\n",
		    username);

	was_spare = pack_long(misc_auth_bytes);

	if (was_spare || flags || expiration || lifetime
	    || (maxAssociates >= 0)) {

	    if (!expiration)
		expiration = uss_Expires;
	    code =
		ubik_KAM_SetFields(uconn_kauthP, 0, username, &instance,
			  flags, expiration, lifetime, maxAssociates,
			  was_spare, /* spare */ 0);
	} else
	    fprintf(stderr,
		    "Must specify one of the optional parameters. Continuing...\n");

	if (code) {
	    afs_com_err(uss_whoami, code, "calling KAM_SetFields for %s",
		    username);

	    return (code);
	}
    } /*Not a dry run */
    else
	fprintf(stderr, "\t[Dry run - user '%s' NOT changed.]\n", username);

    return (0);

}				/*uss_kauth_SetFields */
Example #15
0
int
main(int argc, char **argv)
{
    register afs_int32 code;
    char op[8];
    char name[PR_MAXNAMELEN];
    afs_int32 id, oid = ANONYMOUSID, gid;
    afs_int32 pos;
    unsigned int i;
    int n;
    struct prentry entry;
    prlist alist;
    idlist lid;
    namelist lnames;
    struct hostent *hostinfo;
    struct in_addr *hostaddr;
    afs_int32 *ptr;
    char *foo;
    afs_int32 over;
    char *cell;

#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
    whoami = argv[0];

    initialize_PT_error_table();

    strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
    cell = 0;
    n = 1;
    while (n < argc) {
	int arglen = strlen(argv[n]);
	char arg[256];
	lcstring(arg, argv[n], sizeof(arg));
#define IsArg(a) (strncmp (arg,a, arglen) == 0)
	if (IsArg("-testconfdir"))
	    strncpy(confdir, argv[++n], sizeof(confdir));
	else if (IsArg("client"))
	    strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
	else if (IsArg("server"))
	    strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
	else if (IsArg("0") || IsArg("1") || IsArg("2"))
	    security = atoi(argv[n]);
	else if (IsArg("-ignoreexist"))
	    ignoreExist++;
	else if (IsArg("-cell"))
	    cell = argv[++n];
	else {
	    printf
		("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
	    exit(1);
	}
	n++;
    }

    printf("Using CellServDB file in %s\n", confdir);
    if (security == 0)
	printf("Making unauthenticated connection to prserver\n");

    code = pr_Initialize(security, confdir, cell);
    if (code) {
	afs_com_err(whoami, code, "Couldn't initialize protection library");
	exit(1);
    }

    while (1) {
	char *s;

	printf("pr> ");
	s = fgets(line, sizeof(line), stdin);
	if (s == NULL)
	    break;
	lineProgress = 0;

	code = GetString(op, sizeof(op));
	if (code) {
	    afs_com_err(whoami, PRBADARG,
		    "error reading opcode in line '%s', got '%.*s'", line,
		    sizeof(op), op);
	    exit(1);
	}
	if (strlen(op) == 0)
	    continue;		/* no input */

	if (!strcmp(op, "cr")) {
	    if (GetString(name, sizeof(name)) || GetInt32(&id)
		|| GetInt32(&oid))
		code = PRBADARG;
	    /* use ubik_Call to do the work, finding an up server and handling
	     * the job of finding a sync site, if need be */
	    else
		code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
	} else if (!strcmp(op, "sf")) {
	    afs_int32 mask, access, gq, uq;
	    if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
		|| GetInt32(&gq) || GetInt32(&uq))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
			      access, gq, uq, 0, 0);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
			access, gq, uq);
	} else if (!strcmp(op, "ce")) {
	    char newname[PR_MAXNAMELEN];
	    afs_int32 newid;
	    if (GetInt32(&id) || GetString(newname, sizeof(newname))
		|| GetInt32(&oid) || GetInt32(&newid))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
			      newid);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
			oid, newid);
	} else if (!strcmp(op, "wh")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    else
		printf("location %d\n", pos);
	} else if (!strcmp(op, "du")) {
	    memset(&entry, 0, sizeof(entry));
	    /* scanf("%d",&pos); */
	    if (GetInt32(&pos))
		code = PRBADARG;
	    else
		code = ubik_PR_DumpEntry(pruclient, 0, pos, (struct prdebugentry *)&entry);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		PrintEntry(pos, &entry, /*indent */ 0);
#if 0
		printf("The contents of the entry for %d are:\n", entry.id);
		printf("flags %d next %d\n", entry.flags, entry.next);
		printf("Groups (or members) \n");
		for (i = 0; i < PRSIZE; i++)
		    printf("%d\n", entry.entries[i]);
		printf("nextID %d nextname %d name %s\n", entry.nextID,
		       entry.nextName, entry.name);
		printf("owner %d creator %d\n", entry.owner, entry.creator);
#endif
	    }
	} else if (!strcmp(op, "add") || !strcmp(op, "au")) {
	    /* scanf("%d %d",&id,&gid); */
	    if (GetInt32(&id) || GetInt32(&gid))
		code = PRBADARG;
	    else
		code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
	} else if (!strcmp(op, "iton")) {
	    lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32));
	    ptr = lid.idlist_val;
	    lid.idlist_len = 0;
	    foo = line;
	    skip(&foo);
	    while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
		lid.idlist_len++;
		skip(&foo);
		ptr++;
	    }
	    if (*foo) {
		fprintf(stderr, "too many values specified; max is %d\n", 20);
	    }
	    lnames.namelist_val = 0;
	    lnames.namelist_len = 0;
	    code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		for (i = 0; i < lnames.namelist_len; i++) {
		    printf("id %d name %s\n", lid.idlist_val[i],
			   lnames.namelist_val[i]);
		}
		free(lnames.namelist_val);
	    }
	    free(lid.idlist_val);
	    lid.idlist_val = 0;
	    lid.idlist_len = 0;
	} else if (!strcmp(op, "ntoi")) {
	    lnames.namelist_val =
		(prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN);
	    lnames.namelist_len = 0;
	    foo = line;
	    skip(&foo);
	    for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
			 && (sscanf(foo, "%s", lnames.namelist_val[i]) !=
			     EOF)); i++) {
		lnames.namelist_len++;
		skip(&foo);
	    }
	    if (*foo) {
		fprintf(stderr, "too many values specified; max is %d\n",
			PR_MAXLIST);
	    }
	    lid.idlist_val = 0;
	    lid.idlist_len = 0;
	    code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		for (i = 0; i < lid.idlist_len; i++)
		    printf("name %s id %d\n", lnames.namelist_val[i],
			   lid.idlist_val[i]);
		free(lid.idlist_val);
	    }
	    free(lnames.namelist_val);
	    lnames.namelist_val = 0;
	    lnames.namelist_len = 0;
	} else if (!strcmp(op, "del")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_Delete(pruclient, 0, id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "dg")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_Delete(pruclient, 0, id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "rm")) {
	    /* scanf("%d %d",&id,&gid); */
	    if (GetInt32(&id) || GetInt32(&gid))
		code = PRBADARG;
	    else
		code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	}
#if defined(SUPERGROUPS)
	else if (!strcmp(op, "lsg")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
			      &over);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	}
#endif /* SUPERGROUPS */
	else if (!strcmp(op, "l")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	} else if (!strcmp(op, "lh")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else if (!(hostinfo = gethostbyname(name)))
		code = PRBADARG;
	    else {
		hostaddr = (struct in_addr *)hostinfo->h_addr_list[0];
		id = ntohl(hostaddr->s_addr);
		code =
		    ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
	    }
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	}
#if defined(SUPERGROUPS)
	else if (!strcmp(op, "m")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_ListElements(pruclient, 0, id, &alist,
			      &over);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	}
#endif /* SUPERGROUPS */
	else if (!strcmp(op, "nu")) {
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else
		code = pr_CreateUser(name, &id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("Id is %d.\n", id);
	} else if (!strcmp(op, "ng")) {
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else
		code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("Id is %d.\n", id);
	} else if (!strcmp(op, "lm")) {
	    code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("Max user id is %d, max (really min) group is %d.\n",
		       id, gid);
	} else if (!strcmp(op, "smu")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_SetMax(pruclient, 0, id, 0);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "smg")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_SetMax(pruclient, 0, id, 1);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "sin")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = pr_SIdToName(id, name);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("id %d name %s\n", id, name);
	} else if (!strcmp(op, "sni")) {
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else
		code = pr_SNameToId(name, &id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("name %s id %d\n", name, id);
	} else if (!strcmp(op, "fih")) {
	    char tname[128];
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name))) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SNameToId(name, &id);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SIdToName(id, tname);
	    if (code == PRSUCCESS) {
		printf
		    ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
		     name, id);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_IDHASH;
	    code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
	    if (code) {
		printf("Failed to update entry %s (err=%d)\n", name, code);
		continue;
	    }
	} else if (!strcmp(op, "fnh")) {
	    int tid;
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%d", &id); */
	    if (GetInt32(&id)) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SIdToName(id, name);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SNameToId(name, &tid);
	    if (code == PRSUCCESS) {
		printf
		    ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
		     id, name);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_NAMEHASH;
	    code =
		ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
	    if (code) {
		printf("Failed to update entry with id %d (err=%d)\n", id,
		       code);
		continue;
	    }
	}
#if defined(SUPERGROUPS)
	else if (!strcmp(op, "fih")) {
	    char tname[128];
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name))) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SNameToId(name, &id);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SIdToName(id, tname);
	    if (code == PRSUCCESS) {
		printf
		    ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
		     name, id);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_IDHASH;
	    code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
	    if (code) {
		printf("Failed to update entry %s (err=%d)\n", name, code);
		continue;
	    }
	} else if (!strcmp(op, "fnh")) {
	    int tid;
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%d", &id); */
	    if (GetInt32(&id)) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SIdToName(id, name);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SNameToId(name, &tid);
	    if (code == PRSUCCESS) {
		printf
		    ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
		     id, name);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_NAMEHASH;
	    code =
		ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
	    if (code) {
		printf("Failed to update entry with id %d (err=%d)\n", id,
		       code);
		continue;
	    }
	}
#endif /* SUPERGROUPS */
	else if (!strcmp(op, "?"))
	    PrintHelp();
	else if (!strcmp(op, "q"))
	    exit(0);
	else
	    printf("Unknown op: '%s'! ? for help\n", op);
    }
}
Example #16
0
int
main(int argc, char **argv)
{
    char *whoami = argv[0];
    char *dbNamePtr = 0;
    struct afsconf_cell cellinfo_s;
    struct afsconf_cell *cellinfo = NULL;
    time_t currentTime;
    afs_int32 code = 0;
    afs_uint32 host = ntohl(INADDR_ANY);

    char  clones[MAXHOSTSPERCELL];

    struct rx_service *tservice;
    struct rx_securityClass **securityClasses;
    afs_int32 numClasses;

    extern int rx_stackSize;

#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", whoami);
	exit(1);
    }
#endif

#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);
    sigaction(SIGABRT, &nsa, NULL);
#endif

    memset(&cellinfo_s, 0, sizeof(cellinfo_s));
    memset(clones, 0, sizeof(clones));

    osi_audit_init();
    osi_audit(BUDB_StartEvent, 0, AUD_END);

    initialize_BUDB_error_table();
    initializeArgHandler();

    /* Initialize dirpaths */
    if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
#ifdef AFS_NT40_ENV
	ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
#endif
	afs_com_err(whoami, errno, "; Unable to obtain AFS server directory.");
	exit(2);
    }

    memset(globalConfPtr, 0, sizeof(*globalConfPtr));

    /* set default configuration values */
    strcpy(dbDir, AFSDIR_SERVER_DB_DIRPATH);
    strcat(dbDir, "/");
    globalConfPtr->databaseDirectory = dbDir;
    globalConfPtr->databaseName = DEFAULT_DBPREFIX;
    strcpy(cellConfDir, AFSDIR_SERVER_ETC_DIRPATH);
    globalConfPtr->cellConfigdir = cellConfDir;

    srandom(1);

#ifdef AFS_PTHREAD_ENV
    SetLogThreadNumProgram( rx_GetThreadNum );
#endif

    /* process the user supplied args */
    helpOption = 1;
    code = cmd_Dispatch(argc, argv);
    if (code)
	ERROR(code);

    /* exit if there was a help option */
    if (helpOption)
	BUDB_EXIT(0);

    /* open the log file */
    OpenLog(AFSDIR_SERVER_BUDBLOG_FILEPATH);

    /* open the cell's configuration directory */
    LogDebug(4, "opening %s\n", globalConfPtr->cellConfigdir);

    BU_conf = afsconf_Open(globalConfPtr->cellConfigdir);
    if (BU_conf == 0) {
	LogError(code, "Failed getting cell info\n");
	afs_com_err(whoami, code, "Failed getting cell info");
	ERROR(BUDB_NOCELLS);
    }

    code = afsconf_GetLocalCell(BU_conf, lcell, sizeof(lcell));
    if (code) {
	LogError(0, "** Can't determine local cell name!\n");
	ERROR(code);
    }

    if (globalConfPtr->myHost == 0) {
	/* if user hasn't supplied a list of servers, extract server
	 * list from the cell's database
	 */

	cellinfo = &cellinfo_s;

	LogDebug(1, "Using server list from %s cell database.\n", lcell);

	code = afsconf_GetExtendedCellInfo (BU_conf, lcell, 0, cellinfo,
					    clones);
	if (code) {
	    LogError(0, "Can't read cell information\n");
	    ERROR(code);
	}

	code =
	    convert_cell_to_ubik(cellinfo, &globalConfPtr->myHost,
				 globalConfPtr->serverList);
	if (code)
	    ERROR(code);
    }

    /* initialize audit user check */
    osi_audit_set_user_check(BU_conf, BU_IsLocalRealmMatch);

    /* initialize ubik */
    ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate, BU_conf);
    ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects,
				afsconf_CheckAuth, BU_conf);

    if (ubik_nBuffers == 0)
	ubik_nBuffers = 400;

    LogError(0, "Will allocate %d ubik buffers\n", ubik_nBuffers);

    asprintf(&dbNamePtr, "%s%s", globalConfPtr->databaseDirectory,
	     globalConfPtr->databaseName);
    if (dbNamePtr == 0)
	ERROR(-1);

    rx_SetRxDeadTime(60);	/* 60 seconds inactive before timeout */

    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];
	    rx_InitHost(host, htons(AFSCONF_BUDBPORT));
	}
    }

    /* Disable jumbograms */
    rx_SetNoJumbo();

    if (cellinfo) {
	code = ubik_ServerInitByInfo(globalConfPtr->myHost,
	                             htons(AFSCONF_BUDBPORT),
	                             cellinfo,
	                             clones,
	                             dbNamePtr,           /* name prefix */
	                             &BU_dbase);
    } else {
	code = ubik_ServerInit(globalConfPtr->myHost, htons(AFSCONF_BUDBPORT),
	                       globalConfPtr->serverList,
	                       dbNamePtr,  /* name prefix */
	                       &BU_dbase);
    }

    if (code) {
	LogError(code, "Ubik init failed\n");
	afs_com_err(whoami, code, "Ubik init failed");
	ERROR(code);
    }

    afsconf_BuildServerSecurityObjects(BU_conf, &securityClasses, &numClasses);

    tservice =
	rx_NewServiceHost(host, 0, BUDB_SERVICE, "BackupDatabase",
			  securityClasses, numClasses, BUDB_ExecuteRequest);

    if (tservice == (struct rx_service *)0) {
	LogError(0, "Could not create backup database rx service\n");
	printf("Could not create backup database rx service\n");
	BUDB_EXIT(3);
    }
    rx_SetMinProcs(tservice, 1);
    rx_SetMaxProcs(tservice, lwps);
    rx_SetStackSize(tservice, 10000);

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

    /* misc. initialization */

    /* database dump synchronization */
    memset(dumpSyncPtr, 0, sizeof(*dumpSyncPtr));
    Lock_Init(&dumpSyncPtr->ds_lock);

    rx_StartServer(0);		/* start handling requests */

    code = InitProcs();
    if (code)
	ERROR(code);


    currentTime = time(0);
    LogError(0, "Ready to process requests at %s\n", ctime(&currentTime));

    rx_ServerProc(NULL);		/* donate this LWP */

  error_exit:
    osi_audit(BUDB_FinishEvent, code, AUD_END);
    return (code);
}
Example #17
0
static long
RunHijackTest(struct clientParms *parms, long host,
	      struct rx_securityClass *sc, long si)
{

#ifndef rx_GetPacketCksum

    code = RXKST_BADARGS;
    afs_com_err(whoami, code,
	    "Older versions of Rx don't export packet tracing routines: can't run this HijackTest");
    return code;

#else

    long code;
    struct rx_connection *conn = 0;
    struct rx_connection *otherConn = 0;
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
#else
    PROCESS pid;
#endif
    int nResp;			/* otherConn responses seen */
    long tmp_rc;

#ifdef AFS_PTHREAD_ENV
    pthread_once(&slowCallOnce, SlowCallInit);
#endif
    rx_justReceived = HandleIncoming;
    rx_almostSent = HandleOutgoing;

    incomingOps.op = IO_NOOP;
    outgoingOps.op = OO_NOOP;

#define HIJACK_CONN(conn) \
    {   if (conn) rx_DestroyConnection (conn); \
	(conn) = rx_NewConnection(host, htons(RXKST_SERVICEPORT), \
				RXKST_SERVICEID, sc, si); \
	if (!(conn)) return RXKST_NEWCONNFAILED; \
	outgoingOps.client = 1; \
	outgoingOps.epoch = (conn)->epoch; \
	outgoingOps.cid = (conn)->cid; }

    HIJACK_CONN(conn);

    /* First try switching from no packet cksum to sending packet cksum between
     * calls, and see if server complains. */

    outgoingOps.op = OO_ZEROCKSUM;
    code = FastCall(conn);
    if (code) {
	afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM");
	return code;
    }
    /* The server thinks we're an old style client.  Now start sending cksums.
     * Server shouldn't care. */
    outgoingOps.op = OO_NOOP;
    code = FastCall(conn);
    if (code) {
	afs_com_err(whoami, code, "doing FastCall with non-ZEROCKSUM");
	return code;
    }
    /* The server now thinks we're a new style client, we can't go back now. */
    outgoingOps.op = OO_ZEROCKSUM;
    code = FastCall(conn);
    if (code == 0)
	code = RXKST_NOBADCKSUM;
    if (code != RXKADSEALEDINCON) {
	afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM");
	return code;
    } else if (!conn->error) {
	code = RXKST_NOCONNERROR;
	afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM");
	return code;
    } else
	code = 0;

    HIJACK_CONN(conn);

    /* Now try modifying packet cksum to see if server complains. */

    outgoingOps.op = OO_MUNGCKSUM;
    code = FastCall(conn);
    if (code == 0)
	code = RXKST_NOBADCKSUM;
    if (code != RXKADSEALEDINCON) {
	afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM");
	return code;
    } else if (!conn->error) {
	code = RXKST_NOCONNERROR;
	afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM");
	return code;
    } else
	code = 0;

    /* Now make two connection and direct the first challenge on one connection
     * to the other connection to see if it generates a response.  The
     * retransmitted challenge should allow the call on the first connection to
     * complete correctly.  Part one is to attack a new connection, then attack
     * it after it has made a call.  Part three, just for comparison, attacks a
     * otherConn while it is making a slow call (and thus has an active call).
     * Against this attack we have no defense so we expect a challenge in this
     * case, which the server will discard. */

#define RedirectChallenge(conn,otherConn)	\
    (incomingOps.epoch = (conn)->epoch,		\
     incomingOps.cid = (conn)->cid,		\
     incomingOps.client = 1,			\
     incomingOps.newEpoch = (otherConn)->epoch,	\
     incomingOps.newCid = (otherConn)->cid,	\
     incomingOps.op = IO_REDIRECTCHALLENGE,	\
     outgoingOps.epoch = (otherConn)->epoch,	\
     outgoingOps.cid = (otherConn)->cid,	\
     outgoingOps.client = 1,			\
     outgoingOps.op = OO_COUNT,			\
     outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] = 0)

    HIJACK_CONN(conn);
    HIJACK_CONN(otherConn)
	RedirectChallenge(conn, otherConn);

    code = FastCall(conn);
    if (code)
	return code;
    assert(incomingOps.op == IO_COUNT);	/* redirect code was triggered */
    if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] > 0) {
      oracle:
	code = RXKST_CHALLENGEORACLE;
	afs_com_err(whoami, code, "misdirecting challenge");
	return code;
    }
    code = FastCall(otherConn);	/* generate some activity here */
    if (code)
	return code;
    nResp = outgoingOps.counts[RX_PACKET_TYPE_RESPONSE];
    assert(nResp >= 1);
    code = FastCall(conn);
    if (code)
	return code;
    if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] > nResp)
	goto oracle;

    HIJACK_CONN(conn);
    RedirectChallenge(conn, otherConn);
    /* otherConn was authenticated during part one */
    code = FastCall(conn);
    if (code)
	return code;
    assert(incomingOps.op == IO_COUNT);	/* redirect code was triggered */
    if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] != 0)
	goto oracle;

    HIJACK_CONN(conn);
    RedirectChallenge(conn, otherConn);
    /* otherConn is still authenticated */
    slowCallCode = RXKST_PROCESSCREATED;
#ifdef AFS_PTHREAD_ENV
    {
	pthread_attr_t tattr;

	code = pthread_attr_init(&tattr);
	if (code) {
	    afs_com_err(whoami, code,
		    "can't pthread_attr_init slow call process");
	    return code;
	}

	code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
	if (code) {
	    afs_com_err(whoami, code,
		    "can't pthread_attr_setdetachstate slow call process");
	    return code;
	}

	code = pthread_create(&pid, &tattr, SlowCall, (void *)otherConn);
    }
#else
    code =
	LWP_CreateProcess(SlowCall, 16000, LWP_NORMAL_PRIORITY,
			  (opaque) otherConn, "Slow Call Process", &pid);
#endif
    if (code) {
	afs_com_err(whoami, code, "can't create slow call process");
	return code;
    }
#ifdef AFS_PTHREAD_ENV
    pthread_mutex_lock(&slowCallLock);
    while (slowCallCode == RXKST_PROCESSCREATED)
	pthread_cond_wait(&slowCallCV, &slowCallLock);
#else
    while (slowCallCode == RXKST_PROCESSCREATED)
	LWP_WaitProcess(&slowCallCode);	/* wait for process start */
#endif
    if (slowCallCode != RXKST_PROCESSRUNNING) {
	tmp_rc = slowCallCode;
#ifdef AFS_PTHREAD_ENV
	pthread_mutex_unlock(&slowCallLock);
#endif
	return tmp_rc;		/* make sure didn't fail immediately */
    }
    assert(incomingOps.op == IO_REDIRECTCHALLENGE);
    code = FastCall(conn);
    if (code)
	return code;
    assert(incomingOps.op == IO_COUNT);	/* redirect code was triggered */
#ifdef AFS_PTHREAD_ENV
    while (slowCallCode == RXKST_PROCESSRUNNING)
	pthread_cond_wait(&slowCallCV, &slowCallLock);
    pthread_mutex_unlock(&slowCallLock);
#else
    while (slowCallCode == RXKST_PROCESSRUNNING)
	LWP_WaitProcess(&slowCallCode);	/* wait for process finish */
#endif
    if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] != 1)
	goto oracle;

    rx_justReceived = 0;
    rx_almostSent = 0;
    rx_DestroyConnection(otherConn);
    rx_DestroyConnection(conn);
    return code;

#endif /* rx_GetPacketCksum */

}
Example #18
0
int
CommandProc(struct cmd_syndesc *as, void *arock)
{
    char name[MAXKTCNAMELEN];
    char instance[MAXKTCNAMELEN];
    char cell[MAXKTCREALMLEN];
    char realm[MAXKTCREALMLEN];
    afs_uint32 serverList[MAXSERVERS];
    char *lcell;		/* local cellname */
    char lrealm[MAXKTCREALMLEN];	/* uppercase copy of local cellname */
    int code;
    int i, dosetpag;
    Date lifetime;		/* requested ticket lifetime */

    struct passwd pwent;
    struct passwd *pw = &pwent;
    struct passwd *lclpw = &pwent;
    char passwd[BUFSIZ];

    static char rn[] = "klog";	/*Routine name */
    static int Pipe = 0;	/* reading from a pipe */
    static int Silent = 0;	/* Don't want error messages */

    int explicit;		/* servers specified explicitly */
    int local;			/* explicit cell is same a local one */
    int foundPassword = 0;	/*Not yet, anyway */
    int foundExplicitCell = 0;	/*Not yet, anyway */
    int writeTicketFile = 0;	/* write ticket file to /tmp */
    afs_int32 password_expires = -1;

    char *reason;		/* string describing errors */

    /* 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 -silent switch */
    Silent = (as->parms[aSILENT].items ? 1 : 0);
    Pipe = (as->parms[aPIPE].items ? 1 : 0);

    /* Determine if we should also do a setpag based on -setpag switch */
    dosetpag = (as->parms[aSETPAG].items ? 1 : 0);

    if (as->parms[aTMP].items) {
	writeTicketFile = 1;
    }

    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));
	/* XXX the following is just a hack to handle the afscell environment XXX */
	(void)afsconf_GetCellInfo((struct afsconf_dir *)0, realm, 0,
				  (struct afsconf_cell *)0);
    }

    code = ka_Init(0);
    if (code || !(lcell = ka_LocalCell())) {
      nocell:
	if (!Silent)
	    afs_com_err(rn, code, "Can't get local cell name!");
	KLOGEXIT(code);
    }
    if ((code = ka_CellToRealm(lcell, lrealm, 0)))
	goto nocell;

    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 (!Silent) {
		afs_com_err(rn, code, "could not parse server list");
	    }
	    return code;
	}
	explicit = 1;
    } else
Example #19
0
static long
CallSimultaneously(u_int threads, opaque rock, long (*proc)(int, opaque))
{
    long code;
    int i;
#ifdef AFS_PTHREAD_ENV
    pthread_once(&workerOnce, WorkerInit);
#endif

    workers = 0;
    for (i = 0; i < threads; i++) {
	struct worker *w;
#ifdef AFS_PTHREAD_ENV
	pthread_t pid;
#else
	PROCESS pid;
#endif
	assert(i < MAX_CTHREADS);
	w = (struct worker *)osi_Alloc(sizeof(struct worker));
	memset(w, 0, sizeof(*w));
	w->next = workers;
	workers = w;
	w->index = i;
	w->exitCode = RXKST_PROCESSRUNNING;
	w->rock = rock;
	w->proc = proc;
#ifdef AFS_PTHREAD_ENV
	{
	    pthread_attr_t tattr;

	    code = pthread_attr_init(&tattr);
	    if (code) {
		afs_com_err(whoami, code,
			"can't pthread_attr_init worker process");
		return code;
	    }

	    code =
		pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
	    if (code) {
		afs_com_err(whoami, code,
			"can't pthread_attr_setdetachstate worker process");
		return code;
	    }

	    code = pthread_create(&pid, &tattr, DoWorker, (void *)w);
	}
#else
	code =
	    LWP_CreateProcess(DoWorker, 16000, LWP_NORMAL_PRIORITY,
			      (opaque) w, "Worker Process", &pid);
#endif
	if (code) {
	    afs_com_err(whoami, code, "can't create worker process");
	    return code;
	}
    }
    code = 0;			/* last non-zero code encountered */
#ifdef AFS_PTHREAD_ENV
    pthread_mutex_lock(&workerLock);
#endif
    while (workers) {
	struct worker *w, *prevW, *nextW;
	prevW = 0;
	for (w = workers; w; w = nextW) {
	    nextW = w->next;
	    if (w->exitCode != RXKST_PROCESSRUNNING) {
		if (w->exitCode) {
		    if (code == 0)
			code = w->exitCode;
		}
		if (prevW)
		    prevW->next = w->next;
		else
		    workers = w->next;
		osi_Free(w, sizeof(*w));
		continue;	/* don't bump prevW */
	    }
	    prevW = w;
	}
#ifdef AFS_PTHREAD_ENV
	if (workers)
	    pthread_cond_wait(&workerCV, &workerLock);
#else
	if (workers)
	    LWP_WaitProcess(&workers);
#endif
    }
#ifdef AFS_PTHREAD_ENV
    pthread_mutex_unlock(&workerLock);
#endif
    return code;
}
Example #20
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;
}
Example #21
0
static long
RunCallTest(struct clientParms *parms, long host,
	    struct rx_securityClass *sc, long si)
{
    long code;

#ifndef rx_GetPacketCksum

    code = RXKST_BADARGS;
    afs_com_err(whoami, code,
	    "Older versions of Rx don't support Get/Set callNumber Vector procedures: can't run this CallTest");
    return code;

#else

    int i, ch;
    struct rx_connection *conn;
    long firstCall;
    afs_int32 callNumbers[RX_MAXCALLS];
    long codes[RX_MAXCALLS];
    long retCode = 0;		/* ret. if nothing fatal goes wrong */

    conn =
	rx_NewConnection(host, htons(RXKST_SERVICEPORT), RXKST_SERVICEID, sc,
			 si);
    if (!conn)
	return RXKST_NEWCONNFAILED;

    /* First check the basic behaviour of call number handling */

    code = rxi_GetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    for (i = 0; i < RX_MAXCALLS; i++) {
	if (callNumbers[i] != 0) {
	    fprintf(stderr,
		    "Connection's initial call numbers not zero. call[%d] = %d\n",
		    i, callNumbers[i]);
	    return RXKST_BADCALLNUMBERS;
	}
    }
    code = FastCall(conn);
    if (code)
	return code;
    code = rxi_GetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    firstCall = callNumbers[0];
    code = FastCall(conn);
    if (code)
	return code;
    code = rxi_GetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    if ((callNumbers[0] != firstCall + 1)
	&& ((firstCall == 1) || (firstCall == 2))) {
	/* The call number after the first call should be one or, more likely,
	 * two (if the call is still DALLYing).  Between first and second call,
	 * the call number should have incremented by one. */
	fprintf(stderr,
		"Connection's first channel call number not one. call[%d] = %d\n",
		0, callNumbers[0]);
	return RXKST_BADCALLNUMBERS;
    }
    for (i = 1; i < RX_MAXCALLS; i++) {
	if (callNumbers[i] != 0) {
	    fprintf(stderr,
		    "Connection's other channel call numbers not zero. call[%d] = %d\n",
		    i, callNumbers[i]);
	    return RXKST_BADCALLNUMBERS;
	}
    }
    code = MakeMultiChannelCall(conn, 1, 0, codes);
    if (code)
	return code;

    /* Now try to resend a call that's already been executed by finding a
     * non-zero call number on a channel other than zero and decrementing it by
     * one.  This should appear to the server as a retransmitted call.  Since
     * this is behaving as a broken client different strange behaviors may be
     * exhibited by different servers.  If the response packet to the original
     * call is discarded by the time the "retransmitted" call arrives (perhaps
     * due to high server or client load) there is no way for the server to
     * respond at all.  Further, it seems, that under some cases the connection
     * will be kept alive indefinitely even though the server has discarded the
     * "retransmitted" call and is making no effort to reexecute the call.  To
     * handle these, accept either a timeout (-1) or and INCFAILED error here,
     * also set the connenction HardDeadTime to punt after a reasonable
     * interval. */

    /* short dead time since may we expect some trouble */
    rx_SetConnHardDeadTime(conn, 30);
    code = rxi_GetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    for (ch = 1; ch < RX_MAXCALLS; ch++)
	if (callNumbers[ch] > 1) {
	    callNumbers[ch]--;
	    code = rxi_SetCallNumberVector(conn, callNumbers);
	    if (code)
		return code;
	    break;
	}
    if (ch >= RX_MAXCALLS)	/* didn't find any? all DALLYing? */
	return RXKST_BADCALLNUMBERS;
    code = MakeMultiChannelCall(conn, 1, RXKST_INCFAILED, codes);
    code = CheckCallFailure(conn, codes, code, "retransmitted call");
    if (code && !retCode)
	retCode = code;

    /* Get a fresh connection, becasue if the above failed as it should the
     * connection is dead. */
    rx_DestroyConnection(conn);
    conn =
	rx_NewConnection(host, htons(RXKST_SERVICEPORT), RXKST_SERVICEID, sc,
			 si);
    if (!conn)
	return RXKST_NEWCONNFAILED;

    /* Similarly, but decrement call number by two which should be completely
     * unmistakeable as a broken or malicious client. */

    /* short dead time since may we expect some trouble */
    rx_SetConnHardDeadTime(conn, 30);
    code = MakeMultiChannelCall(conn, 2, 0, codes);
    if (code)
	return code;
    code = rxi_GetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    for (ch = 1; ch < RX_MAXCALLS; ch++)
	if (callNumbers[ch] > 2) {
	    callNumbers[ch] -= 2;
	    code = rxi_SetCallNumberVector(conn, callNumbers);
	    break;
	}
    if (ch >= RX_MAXCALLS)	/* didn't find any? all DALLYing? */
	return RXKST_BADCALLNUMBERS;
    code = MakeMultiChannelCall(conn, 1, -1, codes);
    code = CheckCallFailure(conn, codes, code, "duplicate call");
    if (code && !retCode)
	retCode = code;

    rx_DestroyConnection(conn);
    conn =
	rx_NewConnection(host, htons(RXKST_SERVICEPORT), RXKST_SERVICEID, sc,
			 si);
    if (!conn)
	return RXKST_NEWCONNFAILED;

    /* Next, without waiting for the server to discard its state, we will check
     * to see if the Challenge/Response protocol correctly informs the server
     * of the client's callNumber state.  We do this by artificially increasing
     * the call numbers of a new connection for all channels beyond zero,
     * making a call on channel zero, then resetting the call number for the
     * unused channels back to zero, then making calls on all channels. */

    code = rxi_GetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    for (i = 0; i < RX_MAXCALLS; i++) {
	if (callNumbers[i] != 0)
	    return RXKST_BADCALLNUMBERS;
	callNumbers[i] = 51;	/* an arbitrary value... */
    }
    code = rxi_SetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    code = FastCall(conn);	/* use channel 0 */
    if (code)
	return code;
    code = rxi_GetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    if (callNumbers[0] != 52)
	return RXKST_BADCALLNUMBERS;
    for (i = 1; i < RX_MAXCALLS; i++) {
	if (callNumbers[i] != 51)
	    return RXKST_BADCALLNUMBERS;
	callNumbers[i] = 37;	/* back up a ways */
    }
    code = rxi_SetCallNumberVector(conn, callNumbers);
    if (code)
	return code;
    /* now try calls on all channels... */
    code = MakeMultiChannelCall(conn, 1, -1, codes);
    code =
	CheckCallFailure(conn, codes, code, "alternate channel call replay");
    if (code && !retCode)
	retCode = code;

    rx_DestroyConnection(conn);
    return retCode;

#endif /* rx_GetPacketCksum */

}
Example #22
0
void ViceIDToUsername(char *username, char *realm_of_user, char *realm_of_cell,
                      char * cell_to_use, CREDENTIALS *c,
                      int *status,
                      struct ktc_principal *aclient, struct ktc_principal *aserver, struct ktc_token *atoken)
{
    static char lastcell[MAXCELLCHARS+1] = { 0 };
    static char confname[512] = { 0 };
    char username_copy[BUFSIZ];
    afs_int32 viceId;			/* AFS uid of user */

    if (confname[0] == '\0') {
        strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
        confname[sizeof(confname) - 2] = '\0';
    }

    if (dflag)
        printf("About to resolve name %s to id\n", username);

    strcpy(lastcell, aserver->cell);

    if (!pr_Initialize (0, confname, aserver->cell)) {
        char sname[PR_MAXNAMELEN], *at;

        strncpy(sname, username, PR_MAXNAMELEN);
        sname[PR_MAXNAMELEN-1] = '\0';

	at = strchr(sname, '@');
	if (at && !stricmp(at+1, realm_of_cell))
	    *at = '\0';
	*status = pr_SNameToId (sname, &viceId);
    }

    if (dflag)
    {
        if (*status)
            printf("pr_SNameToId Error %s\n",  afs_error_message(*status));
        else
            printf("Id %d\n", viceId);
    }

    /*
     * This code is taken from cklog -- it lets people
     * automatically register with the ptserver in foreign cells
     */

#ifdef ALLOW_REGISTER
    if (*status == 0) {
        if (viceId != ANONYMOUSID) {
#else /* ALLOW_REGISTER */
            if ((*status == 0) && (viceId != ANONYMOUSID))
#endif /* ALLOW_REGISTER */
            {
#ifdef AFS_ID_TO_NAME
                strncpy(username_copy, username, BUFSIZ);
                snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
#endif /* AFS_ID_TO_NAME */
            }
#ifdef ALLOW_REGISTER
        } else if (strcmp(realm_of_user, realm_of_cell) != 0) {
            int i;
            int flags = 0;
            char * smbname = NULL;

            if (dflag) {
                printf("doing first-time registration of %s "
                        "at %s\n", username, cell_to_use);
            }
            strncpy(aclient->name, username, MAXKTCNAMELEN - 1);
            aclient->name[MAXKTCNAMELEN - 1] = '\0';
            strcpy(aclient->instance, "");
            strncpy(aclient->cell, cell_to_use, MAXKTCREALMLEN - 1);
            aclient->cell[MAXKTCREALMLEN - 1] = '\0';

            for ( i=0; aclient->cell[i]; i++ ) {
                if ( islower(aclient->cell[i]) )
                    aclient->cell[i] = toupper(aclient->cell[i]);
            }

            smbname = getenv("AFS_SMBNAME");
            if ( smbname ) {
                strncpy(aclient->smbname, smbname, MAXKTCNAMELEN - 1);
                aclient->smbname[MAXKTCNAMELEN - 1] = '\0';
                flags = AFS_SETTOK_LOGON;
                if (dflag)
                    printf("obtaining tokens for %s\n", aclient->smbname);
            }

            if ((*status = ktc_SetToken(aserver, atoken, aclient, flags))) {
                afs_com_err(progname, *status,
                             "while obtaining tokens for cell %s\n",
                             cell_to_use);
                *status = AKLOG_TOKEN;
                return ;
            }

            /*
             * In case you're wondering, we don't need to change the
             * filename here because we're still connecting to the
             * same cell -- we're just using a different authentication
             * level
             */

            if ((*status = pr_Initialize(1L, confname, aserver->cell))) {
                printf("pr_Initialize Error %s\n",  afs_error_message(*status));
                return;
            }

            /* copy the name because pr_CreateUser lowercases the realm */
            strncpy(username_copy, username, BUFSIZ);

            viceId = 0;
            *status = pr_CreateUser(username_copy, &viceId);

            if (*status) {
                printf("%s: unable to create remote PTS "
                        "user %s in cell %s (status: %s).\n", progname,
                        username_copy, cell_to_use, afs_error_message(*status));
            } else {
                printf("created cross-cell entry for %s (Id %d) at %s\n",
                        username_copy, viceId, cell_to_use);
#ifdef AFS_ID_TO_NAME
                snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
#endif /* AFS_ID_TO_NAME */
            }
        }
    }
#endif /* ALLOW_REGISTER */
}
Example #23
0
int
bc_ParseDumpSchedule(void)
{
    char tbuffer[1024];
    char dsname[256], period[64];
    char *tp;
    afs_int32 code;
    udbClientTextP ctPtr;
    struct bc_dumpSchedule *tds;
    struct bc_dumpSchedule **ppds, *pds;
    afs_int32 expDate, expType;

    FILE *stream;

    /* initialize locally used variables */
    ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
    stream = ctPtr->textStream;

    if (ctPtr->textSize == 0)	/* nothing defined yet */
	return (0);

    if (stream == NULL)
	return (BC_INTERNALERROR);

    rewind(stream);

    /* check the magic number and version */
    tp = fgets(tbuffer, sizeof(tbuffer), stream);
    if (tp == 0)
	/* can't read first line - error */
	return (BC_INTERNALERROR);
    else {
	afs_int32 dsmagic, dsversion;

	/* read the first line, and then check magic # and version */

	code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
	if ((code != 2)
	    || (dsmagic != BC_SCHEDULE_MAGIC)
	    || (dsversion != BC_SCHEDULE_VERSION)
	    ) {
	    /* invalid or unexpected header - error */
	    afs_com_err(whoami, 0, "Unable to understand dump schedule file");
	    return (BC_INTERNALERROR);
	}
    }

    while (1) {
	/* read all of the lines out */
	tp = fgets(tbuffer, sizeof(tbuffer), stream);
	if (tp == 0)
	    break;		/* hit eof? */
	code =
	    sscanf(tbuffer, "%s %s %d %d", dsname, period, &expDate,
		   &expType);
	if (code != 4) {
	    afs_com_err(whoami, 0,
		    "Syntax error in dump schedule file, line is: %s",
		    tbuffer);
	    return (BC_INTERNALERROR);
	}
	tds =
	    (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
	memset(tds, 0, sizeof(*tds));

	tds->next = (struct bc_dumpSchedule *)0;
	tds->name = (char *)malloc(strlen(dsname) + 1);
	strcpy(tds->name, dsname);

	tds->expDate = expDate;
	tds->expType = expType;

	/* find the end of the schedule list, and append the new item to it */
	ppds = &bc_globalConfig->dsched;
	pds = *ppds;
	while (pds != 0) {
	    ppds = &pds->next;
	    pds = *ppds;
	}
	*ppds = tds;
    }
    return 0;
}
Example #24
0
/*
* Log to a cell.  If the cell has already been logged to, return without
* doing anything.  Otherwise, log to it and mark that it has been logged
* to.  */
static int auth_to_cell(krb5_context context, char *cell, char *realm)
{
    int status = AKLOG_SUCCESS;
    char username[BUFSIZ];	  /* To hold client username structure */

    char name[ANAME_SZ];	  /* Name of afs key */
    char instance[INST_SZ];	  /* Instance of afs key */
    char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
    char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
    char local_cell[MAXCELLCHARS+1];
    char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */

    krb5_creds *v5cred = NULL;
#ifdef HAVE_KRB4
    CREDENTIALS c;
#endif
    struct ktc_principal aserver;
    struct ktc_principal aclient;
    struct ktc_token atoken, btoken;
    struct afsconf_cell ak_cellconfig; /* General information about the cell */
    int i;
    int getLinkedCell = 0;
    int flags = 0;
    char * smbname = getenv("AFS_SMBNAME");

    /* try to avoid an expensive call to get_cellconfig */
    if (cell && ll_string_check(&authedcells, cell))
    {
        if (dflag)
            printf("Already authenticated to %s (or tried to)\n", cell);
        return(AKLOG_SUCCESS);
    }

    memset(name, 0, sizeof(name));
    memset(instance, 0, sizeof(instance));
    memset(realm_of_user, 0, sizeof(realm_of_user));
    memset(realm_of_cell, 0, sizeof(realm_of_cell));
    memset(&ak_cellconfig, 0, sizeof(ak_cellconfig));

    /* NULL or empty cell returns information on local cell */
    if (status = get_cellconfig(cell, &ak_cellconfig, local_cell))
        return(status);

  linkedCell:
    if (getLinkedCell)
        strncpy(cell_to_use, ak_cellconfig.linkedCell, MAXCELLCHARS);
    else
        strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
    cell_to_use[MAXCELLCHARS] = 0;

    if (ll_string_check(&authedcells, cell_to_use))
    {
        if (dflag)
            printf("Already authenticated to %s (or tried to)\n", cell_to_use);
        status = AKLOG_SUCCESS;
        goto done2;
    }

    /*
     * Record that we have attempted to log to this cell.  We do this
     * before we try rather than after so that we will not try
     * and fail repeatedly for one cell.
     */
    (void)ll_add_string(&authedcells, cell_to_use);

    if (dflag)
        printf("Authenticating to cell %s.\n", cell_to_use);

    /* We use the afs.<cellname> convention here... */
    strcpy(name, AFSKEY);
    strncpy(instance, cell_to_use, sizeof(instance));
    instance[sizeof(instance)-1] = '\0';

    /*
     * Extract the session key from the ticket file and hand-frob an
     * afs style authenticator.
     */

    if (usev5)
    { /* using krb5 */
        int retry = 1;
	int realm_fallback = 0;

        if ((status = get_v5_user_realm(context, realm_of_user)) != KSUCCESS) {
            char * msg;

            msg = krb5_get_error_message(context, status);
            fprintf(stderr, "%s: Couldn't determine realm of user: %s\n",
                    progname, msg);
            krb5_free_error_message(context, msg);
            status = AKLOG_KERBEROS;
            goto done;
        }

        if ( strchr(name,'.') != NULL && !accept_dotted_usernames()) {
            fprintf(stderr, "%s: Can't support principal names including a dot.\n",
                    progname);
            status = AKLOG_MISC;
            goto done;
        }

      try_v5:
	if (realm && realm[0]) {
            if (dflag)
                printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm);
            status = get_v5cred(context, name, instance, realm,
#ifdef HAVE_KRB4
                            use524 ? &c : NULL,
#else
                            NULL,
#endif
                            &v5cred);
            strcpy(realm_of_cell, realm);
        } else {
	    strcpy(realm_of_cell,
		    afs_realm_of_cell5(context, &ak_cellconfig, realm_fallback));

            if (retry == 1 && realm_fallback == 0) {
                /* Only try the realm_of_user once */
                status = -1;
                if (dflag)
                    printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_user);
                status = get_v5cred(context, name, instance, realm_of_user,
#ifdef HAVE_KRB4
                                     use524 ? &c : NULL,
#else
                                     NULL,
#endif
                                     &v5cred);
                if (status == 0) {
                    /* we have determined that the client realm
                     * is a valid cell realm
                     */
                    strcpy(realm_of_cell, realm_of_user);
                }
            }

            if (status != 0 && (!retry || retry && strcmp(realm_of_user,realm_of_cell))) {
                if (dflag)
                    printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_cell);
                status = get_v5cred(context, name, instance, realm_of_cell,
#ifdef HAVE_KRB4
                                     use524 ? &c : NULL,
#else
                                     NULL,
#endif
                                     &v5cred);
                if (!status && !strlen(realm_of_cell))
                    copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred);
            }
        }

	if (!realm_fallback && status == KRB5_ERR_HOST_REALM_UNKNOWN) {
	    realm_fallback = 1;
	    goto try_v5;
	} else if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) {
	    if (!realm_fallback && !realm_of_cell[0]) {
		realm_fallback = 1;
		goto try_v5;
	    }
            if (dflag)
                printf("Getting v5 tickets: %s@%s\n", name, realm_of_cell);
            status = get_v5cred(context, name, "", realm_of_cell,
#ifdef HAVE_KRB4
                                use524 ? &c : NULL,
#else
                                NULL,
#endif
                                &v5cred);
            if (!status && !strlen(realm_of_cell))
                copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred);
	}

        if ( status == KRB5KRB_AP_ERR_MSG_TYPE && retry ) {
            retry = 0;
	    realm_fallback = 0;
            goto try_v5;
        }
    }
    else
    {
#ifdef HAVE_KRB4
	if (realm && realm[0])
	    strcpy(realm_of_cell, realm);
	else
	    strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));

	/*
         * Try to obtain AFS tickets.  Because there are two valid service
         * names, we will try both, but trying the more specific first.
         *
         * 	afs.<cell>@<realm>
         * 	afs@<realm>
         */
        if (dflag)
            printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell);
        status = get_cred(name, instance, realm_of_cell, &c);
        if (status == KDC_PR_UNKNOWN)
        {
            if (dflag)
                printf("Getting tickets: %s@%s\n", name, realm_of_cell);
            status = get_cred(name, "", realm_of_cell, &c);
        }
#else
        status = AKLOG_MISC;
        goto done;
#endif
    }

    if (status != KSUCCESS)
    {
        char * msg = NULL;
        if (dflag)
            printf("Kerberos error code returned by get_cred: %d\n", status);

        if (usev5) {
            msg = krb5_get_error_message(context, status);
        }
#ifdef HAVE_KRB4
        else
            msg = krb_err_text(status);
#endif
        fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n",
                progname, cell_to_use, msg?msg:"(unknown error)");
        if (usev5)
            krb5_free_error_message(context, msg);
        status = AKLOG_KERBEROS;
        goto done;
    }

    strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1);
    strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1);
    strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1);

    if (usev5 && !use524) {
        /* This code inserts the entire K5 ticket into the token
         * No need to perform a krb524 translation which is
         * commented out in the code below
         */
        char * p;
        int len;
        const char *un;

        un = krb5_principal_get_comp_string(context, v5cred->client, 0);
        strncpy(username, un, MAXKTCNAMELEN - 1);
        username[MAXKTCNAMELEN - 1] = '\0';

        if ( krb5_principal_get_num_comp(context, v5cred->client) > 1 ) {
            strcat(username, ".");
            p = username + strlen(username);
            len = (unsigned int)(MAXKTCNAMELEN - strlen(username) - 1);
            strncpy(p, krb5_principal_get_comp_string(context, v5cred->client, 1), len);
            p[len] = '\0';
        }

        memset(&atoken, '\0', sizeof(atoken));
        atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
        atoken.startTime = v5cred->times.starttime;
        atoken.endTime = v5cred->times.endtime;
	if (tkt_DeriveDesKey(v5cred->session.keytype,
			     v5cred->session.keyvalue.data,
			     v5cred->session.keyvalue.length, &atoken.sessionKey)) {
	    status = AKLOG_MISC;
	    goto done;
	}
        atoken.ticketLen = v5cred->ticket.length;
        memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
    } else {
#ifdef HAVE_KRB4
        strcpy (username, c.pname);
        if (c.pinst[0])
        {
            strcat(username, ".");
            strcat(username, c.pinst);
        }

        atoken.kvno = c.kvno;
        atoken.startTime = c.issue_date;
        /* ticket lifetime is in five-minutes blocks. */
        atoken.endTime = c.issue_date + ((unsigned char)c.lifetime * 5 * 60);

        memcpy(&atoken.sessionKey, c.session, 8);
        atoken.ticketLen = c.ticket_st.length;
        memcpy(atoken.ticket, c.ticket_st.dat, atoken.ticketLen);
#else
        status = AKLOG_MISC;
        goto done;
#endif
    }

    if (!force &&
        !smbname &&
        !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) &&
        atoken.kvno == btoken.kvno &&
        atoken.ticketLen == btoken.ticketLen &&
        !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
        !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
    {
        if (dflag)
            printf("Identical tokens already exist; skipping.\n");
        status = AKLOG_SUCCESS;
        goto done2;
    }

    if (noprdb)
    {
        if (dflag)
            printf("Not resolving name %s to id (-noprdb set)\n", username);
    }
    else
    {
        if (!usev5) {
#ifdef HAVE_KRB4
            if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS)
            {
                fprintf(stderr, "%s: Couldn't determine realm of user: %s)",
                         progname, krb_err_text(status));
                status = AKLOG_KERBEROS;
                goto done;
            }
#else
            status = AKLOG_MISC;
            goto done;
#endif
        }

        /* For Network Identity Manager append the realm to the name */
        strcat(username, "@");
        strcat(username, realm_of_user);

        ViceIDToUsername(username, realm_of_user, realm_of_cell, cell_to_use,
#ifdef HAVE_KRB4
                          &c,
#else
                          NULL,
#endif
                          &status, &aclient, &aserver, &atoken);
    }

    if (dflag)
        printf("Set username to %s\n", username);

    /* Reset the "aclient" structure before we call ktc_SetToken.
     * This structure was first set by the ktc_GetToken call when
     * we were comparing whether identical tokens already existed.
     */
    strncpy(aclient.name, username, MAXKTCNAMELEN - 1);
    strcpy(aclient.instance, "");

    if (usev5 && !use524) {
        strncpy(aclient.cell,
                krb5_principal_get_realm(context, v5cred->client), MAXKTCNAMELEN - 1);
        aclient.cell[MAXKTCNAMELEN - 1] = '\0';
    }
#ifdef HAVE_KRB4
    else
	strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1);
#endif

    for ( i=0; aclient.cell[i]; i++ ) {
        if ( islower(aclient.cell[i]) )
            aclient.cell[i] = toupper(aclient.cell[i]);
    }

    if ( smbname ) {
        if (dflag)
            printf("Setting tokens for %s.\n", smbname);

        strncpy(aclient.smbname, smbname, MAXKTCNAMELEN - 1);
        aclient.smbname[MAXKTCNAMELEN - 1] = '\0';
        flags = AFS_SETTOK_LOGON;
    } else {
        if (dflag)
            printf("Setting tokens.\n");
    }

    if (status = ktc_SetToken(&aserver, &atoken, &aclient, flags))
    {
        afs_com_err(progname, status,
                     "while setting token for cell %s\n",
                     cell_to_use);
        status = AKLOG_TOKEN;
    }

  done2:
    if (ak_cellconfig.linkedCell && !getLinkedCell) {
        getLinkedCell = 1;
        goto linkedCell;
    }

  done:
#if 0
    /*
     * intentionally leak the linkedCell field because it was allocated
     * using a different C RTL version.
     */
    if (ak_cellconfig.linkedCell)
        free(ak_cellconfig.linkedCell);
#endif
    return(status);
}
Example #25
0
int main(int argc, char **argv)
{
    struct afsconf_dir *dir;
    char *dirname;
    int serverPid, clientPid, waited, stat;
    int code;

    /* Start the client and the server if requested */

    if (argc == 3 ) {
        if (strcmp(argv[1], "-server") == 0) {
	    globalDir = afsconf_Open(argv[2]);
	    afstest_StartTestRPCService(argv[2], TEST_PORT, TEST_SERVICE_ID,
					TEST_ExecuteRequest);
            exit(0);
        } else if (strcmp(argv[1], "-client") == 0) {
            startClient(argv[2]);
            exit(0);
        } else {
            printf("Bad option %s\n", argv[1]);
            exit(1);
        }
    }

    /* Otherwise, do the basic configuration, then start the client and
     * server */

    dirname = afstest_BuildTestConfig();

    dir = afsconf_Open(dirname);
    if (dir == NULL) {
	fprintf(stderr, "Unable to configure directory.\n");
	exit(1);
    }

    code = afstest_AddDESKeyFile(dir);
    if (code) {
	afs_com_err("superuser-t", code, "while adding new key\n");
	exit(1);
    }

    printf("Config directory is %s\n", dirname);
    serverPid = fork();
    if (serverPid == -1) {
        /* Bang */
    } else if (serverPid == 0) {
        execl(argv[0], argv[0], "-server", dirname, NULL);
        exit(1);
    }
    clientPid = fork();
    if (clientPid == -1) {
        kill(serverPid, SIGTERM);
        waitpid(serverPid, &stat, 0);
        exit(1);
    } else if (clientPid == 0) {
        execl(argv[0], argv[0], "-client", dirname, NULL);
    }

    do {
        waited = waitpid(0, &stat, 0);
    } while(waited == -1 && errno == EINTR);

    if (waited == serverPid) {
        kill(clientPid, SIGTERM);
    } else if (waited == clientPid) {
        kill(serverPid, SIGTERM);
    }
    waitpid(0, &stat, 0);

    /* Client and server are both done, so cleanup after everything */

    /* unlinkTestConfig(dirname); */

    return 0;
}
Example #26
0
static int
Main(struct cmd_syndesc *as, void *arock)
{
    int code;
    char name[MAXKTCNAMELEN];
    char instance[MAXKTCNAMELEN];
    char newCell[MAXKTCREALMLEN];
    char *cell;

    long serverList[MAXSERVERS];
    extern struct passwd *getpwuid();

    struct passwd *pw;
    struct ktc_encryptionKey key;

    char passwd[BUFSIZ];

    int cellSpecified;
    int i;
    int verbose = (as->parms[1].items != 0);
    int hostUsage = (as->parms[2].items != 0);
    int waitReap = (as->parms[4].items != 0);
    int doAuth = (as->parms[5].items != 0);
    int number;			/* number of iterations */
    int callsPerSecond;		/* to allow conn GC to run */

    unsigned long lo, hi;	/* mem usage */
    unsigned long highWater;	/* mem usage after reap period */
    unsigned long lastWater;	/* mem usage after last msg */
    int serversUse[MAXSERVERS];	/* usage of each server */
    long serversHost[MAXSERVERS];	/* host addr */
    unsigned long startTime;
    unsigned long now;

    lo = 0;
    whoami = as->a0name;
    newCell[0] = 0;

    if (as->parms[0].items)
	number = atoi(as->parms[0].items->data);
    else
	number = 100;
    if (as->parms[3].items)
	callsPerSecond = atoi(as->parms[3].items->data);
    else
	callsPerSecond = 1;
    if (doAuth && hostUsage) {
	fprintf(stderr,
		"Can't report host usage when calling UserAuthenticate\n");
	return -1;
    }

    if (as->parms[12].items) {	/* if username specified */
	code =
	    ka_ParseLoginName(as->parms[12].items->data, name, instance,
			      newCell);
	if (code) {
	    afs_com_err(whoami, code, "parsing user's name '%s'",
		    as->parms[12].items->data);
	    return code;
	}
	if (strlen(newCell) > 0)
	    cellSpecified = 1;
    } else {
	/* No explicit name provided: use Unix uid. */
	pw = getpwuid(getuid());
	if (pw == 0) {
	    printf("Can't figure out your name from your user id.\n");
	    return KABADCMD;
	}
	strncpy(name, pw->pw_name, sizeof(name));
	strcpy(instance, "");
	strcpy(newCell, "");
    }
    if (strcmp(as->parms[14].name, "-cell") == 0) {
	if (as->parms[14].items) {	/* if cell specified */
	    if (cellSpecified)
		printf("Duplicate cell specification not allowed\n");
	    else
		strncpy(newCell, as->parms[14].items->data, sizeof(newCell));
	}
    }

    code = ka_ExpandCell(newCell, newCell, 0 /*local */ );
    if (code) {
	afs_com_err(whoami, code, "Can't expand cell name");
	return code;
    }
    cell = newCell;

    if (as->parms[13].items) {	/* if password specified */
	strncpy(passwd, as->parms[13].items->data, sizeof(passwd));
	memset(as->parms[13].items->data, 0,
	       strlen(as->parms[13].items->data));
    } else {
	char msg[sizeof(name) + 15];
	if (as->parms[12].items)
	    strcpy(msg, "Admin Password: "******"Password for %s: ", name);
	code = read_pw_string(passwd, sizeof(passwd), msg, 0);
	if (code)
	    code = KAREADPW;
	else if (strlen(passwd) == 0)
	    code = KANULLPASSWORD;
	if (code) {
	    afs_com_err(whoami, code, "reading password");
	    return code;
	}
    }
    if (as->parms[15].items) {
	struct cmd_item *ip;
	char *ap[MAXSERVERS + 2];

	for (ip = as->parms[15].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) {
	    afs_com_err(whoami, code, "could not parse server list");
	    return code;
	}
	ka_ExplicitCell(cell, serverList);
    }

    if (!doAuth) {
	ka_StringToKey(passwd, cell, &key);
	memset(passwd, 0, sizeof(passwd));
    }
    if (hostUsage) {
	memset(serversUse, 0, sizeof(serversUse));
	memset(serversHost, 0, sizeof(serversHost));
    }

    startTime = time(0);
    for (i = 0; i < number; i++) {
	if (doAuth) {
	    char *reason;
	    code =
		ka_UserAuthenticateLife(0, name, instance, cell, passwd, 0,
					&reason);
	    if (code) {
		fprintf(stderr, "Unable to authenticate to AFS because %s.\n",
			reason);
		return code;
	    }
	} else {
	    struct ktc_token token;
	    struct ktc_token *pToken;
	    struct ubik_client *ubikConn;
	    struct kaentryinfo tentry;
	    int c;

	    code =
		ka_GetAdminToken(name, instance, cell, &key, 3600, &token,
				 1 /*new */ );
	    if (code) {
		afs_com_err(whoami, code, "getting admin token");
		return code;
	    }
	    pToken = &token;
	    if (token.ticketLen == 0) {
		fprintf("Can't get admin token\n");
		return -1;
	    }

	    code =
		ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, pToken,
				  &ubikConn);
	    if (code) {
		afs_com_err(whoami, code, "Getting AuthServer ubik conn");
		return code;
	    }

	    if (verbose)
		for (c = 0; c < MAXSERVERS; c++) {
		    struct rx_connection *rxConn =
			ubik_GetRPCConn(ubikConn, c);
		    struct rx_peer *peer;

		    if (rxConn == 0)
			break;
		    peer = rx_PeerOf(rxConn);
		    printf("conn to %s:%d secObj:%x\n",
			   inet_ntoa(rx_HostOf(peer)), ntohs(rx_PortOf(peer)),
			   rxConn->securityObject);
		}

	    code =
		ubik_Call(KAM_GetEntry, ubikConn, 0, name, instance,
			  KAMAJORVERSION, &tentry);
	    if (code) {
		afs_com_err(whoami, code, "getting information for %s.%s", name,
			instance);
		return code;
	    }

	    for (c = 0; c < MAXSERVERS; c++) {
		struct rx_connection *rxConn = ubik_GetRPCConn(ubikConn, c);
		int d;
		if (rxConn == 0)
		    break;
		if (rxConn->serial > 0) {
		    long host = rx_HostOf(rx_PeerOf(rxConn));
		    for (d = 0; d < MAXSERVERS; d++) {
			if (serversHost[d] == 0)
			    serversHost[d] = host;
			if (host == serversHost[d]) {
			    serversUse[d]++;
			    break;
			}
		    }
		}
		if (verbose)
		    printf("serial is %d\n", rxConn->serial);
	    }
	    ubik_ClientDestroy(ubikConn);
	}

	now = time(0);
	if (!lo)
	    lo = sbrk(0);
	if (i && ((i & 0x3f) == 0)) {
	    unsigned long this = sbrk(0);
	    printf("  mem after %d: lo=%x, cur=%x => %d (@ %d)\n", i, lo,
		   this, this - lo, (this - lo) / i);
	    if (highWater && (lastWater != this)) {
		lastWater = this;
		printf("  core leaking (after %d) should be %x, is %x\n", i,
		       highWater, this);
	    }
	}
	if ((highWater == 0) && ((now - startTime) > 61)) {
	    highWater = sbrk(0);
	    lastWater = highWater;
	    printf("  mem highWater mark (after %d) should be %x\n", i,
		   highWater);
	}
	if (callsPerSecond) {
	    long target;
	    if (callsPerSecond > 0)
		target = i / callsPerSecond;
	    else		/* if negative interpret as seconds per call */
		target = i * (-callsPerSecond);
	    target = (startTime + target) - now;
	    if (target > 0)
		IOMGR_Sleep(target);
	}
    }
Example #27
0
int
main(int argc, char **argv)
{
    afs_int32 code;
    afs_uint32 myHost;
    struct hostent *th;
    char hostname[64];
    struct rx_service *tservice;
    struct rx_securityClass **securityClasses;
    afs_int32 numClasses;
    int lwps = 3;
    char clones[MAXHOSTSPERCELL];
    afs_uint32 host = htonl(INADDR_ANY);
    struct cmd_syndesc *opts;
    struct cmd_item *list;

    char *pr_dbaseName;
    char *configDir;
    char *logFile;
    char *whoami = "ptserver";

    char *auditFileName = NULL;
    char *interface = NULL;

#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(SIGABRT, &nsa, NULL);
    sigaction(SIGSEGV, &nsa, NULL);
#endif
    osi_audit_init();
    osi_audit(PTS_StartEvent, 0, AUD_END);

    /* 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);
    }

    pr_dbaseName = strdup(AFSDIR_SERVER_PRDB_FILEPATH);
    configDir = strdup(AFSDIR_SERVER_ETC_DIRPATH);
    logFile = strdup(AFSDIR_SERVER_PTLOG_FILEPATH);

#if defined(SUPERGROUPS)
    /* make sure the structures for database records are the same size */
    if ((sizeof(struct prentry) != ENTRYSIZE)
	|| (sizeof(struct prentryg) != ENTRYSIZE)) {
	fprintf(stderr,
		"The structures for the database records are different"
		" sizes\n" "struct prentry = %" AFS_SIZET_FMT "\n"
                "struct prentryg = %" AFS_SIZET_FMT "\n"
		"ENTRYSIZE = %d\n", sizeof(struct prentry),
		sizeof(struct prentryg), ENTRYSIZE);
	PT_EXIT(1);
    }
#endif

    cmd_DisableAbbreviations();
    cmd_DisablePositionalCommands();
    opts = cmd_CreateSyntax(NULL, NULL, NULL, NULL);

/* ptserver specific options */
    cmd_AddParmAtOffset(opts, OPT_database, "-database", CMD_SINGLE,
		        CMD_OPTIONAL, "database file");
    cmd_AddParmAlias(opts, OPT_database, "db");

    cmd_AddParmAtOffset(opts, OPT_access, "-default_access", CMD_SINGLE,
		        CMD_OPTIONAL, "default access flags for new entries");
#if defined(SUPERGROUPS)
    cmd_AddParmAtOffset(opts, OPT_groupdepth, "-groupdepth", CMD_SINGLE,
		        CMD_OPTIONAL, "max search depth for supergroups");
    cmd_AddParmAlias(opts, OPT_groupdepth, "depth");
#endif
    cmd_AddParmAtOffset(opts, OPT_restricted, "-restricted", CMD_FLAG,
		        CMD_OPTIONAL, "enable restricted mode");

    /* general server options */
    cmd_AddParmAtOffset(opts, OPT_auditlog, "-auditlog", CMD_SINGLE,
		 	CMD_OPTIONAL, "location of audit log");
    cmd_AddParmAtOffset(opts, OPT_auditiface, "-audit-interface", CMD_SINGLE,
		        CMD_OPTIONAL, "interface to use for audit logging");
    cmd_AddParmAtOffset(opts, OPT_config, "-config", CMD_SINGLE,
		        CMD_OPTIONAL, "configuration location");
    cmd_AddParmAtOffset(opts, OPT_debug, "-d", CMD_SINGLE,
		        CMD_OPTIONAL, "debug level");
    cmd_AddParmAtOffset(opts, OPT_logfile, "-logfile", CMD_SINGLE,
		        CMD_OPTIONAL, "location of logfile");
    cmd_AddParmAtOffset(opts, OPT_threads, "-p", CMD_SINGLE,
		        CMD_OPTIONAL, "number of threads");
#if !defined(AFS_NT40_ENV)
    cmd_AddParmAtOffset(opts, OPT_syslog, "-syslog", CMD_SINGLE_OR_FLAG, 
		        CMD_OPTIONAL, "log to syslog");
#endif

    /* rx options */
    cmd_AddParmAtOffset(opts, OPT_peer, "-enable_peer_stats", CMD_FLAG,
		        CMD_OPTIONAL, "enable RX transport statistics");
    cmd_AddParmAtOffset(opts, OPT_process, "-enable_process_stats", CMD_FLAG,
		        CMD_OPTIONAL, "enable RX RPC statistics");
    cmd_AddParmAtOffset(opts, OPT_rxbind, "-rxbind", CMD_FLAG,
		        CMD_OPTIONAL, "bind only to the primary interface");
    cmd_AddParmAtOffset(opts, OPT_rxmaxmtu, "-rxmaxmtu", CMD_SINGLE,
		        CMD_OPTIONAL, "maximum MTU for RX");

    /* rxkad options */
    cmd_AddParmAtOffset(opts, OPT_dotted, "-allow-dotted-principals",
		        CMD_FLAG, CMD_OPTIONAL,
		        "permit Kerberos 5 principals with dots");

    code = cmd_Parse(argc, argv, &opts);
    if (code)
	PT_EXIT(1);

    cmd_OptionAsString(opts, OPT_config, &configDir);

    cmd_OpenConfigFile(AFSDIR_SERVER_CONFIG_FILE_FILEPATH);
    cmd_SetCommandName("ptserver");

    if (cmd_OptionAsList(opts, OPT_access, &list) == 0) {
	prp_user_default = prp_access_mask(list->data);
	if (list->next == NULL || list->next->data == NULL) {
	    fprintf(stderr, "Missing second argument for -default_access\n");
	    PT_EXIT(1);
	}
	prp_group_default = prp_access_mask(list->next->data);
    }

#if defined(SUPERGROUPS)
    cmd_OptionAsInt(opts, OPT_groupdepth, &depthsg);
#endif

    cmd_OptionAsFlag(opts, OPT_restricted, &restricted);

    /* general server options */
    cmd_OptionAsString(opts, OPT_auditlog, &auditFileName);

    if (cmd_OptionAsString(opts, OPT_auditiface, &interface) == 0) {
	if (osi_audit_interface(interface)) {
	    printf("Invalid audit interface '%s'\n", interface);
	    PT_EXIT(1);
	}
	free(interface);
    }

    cmd_OptionAsInt(opts, OPT_debug, &LogLevel);
    cmd_OptionAsString(opts, OPT_database, &pr_dbaseName);
    cmd_OptionAsString(opts, OPT_logfile, &logFile);

    if (cmd_OptionAsInt(opts, OPT_threads, &lwps) == 0) {
	if (lwps > 64) {	/* maximum of 64 */
	    printf("Warning: '-p %d' is too big; using %d instead\n",
		   lwps, 64);
	    lwps = 64;
	} else if (lwps < 3) {	/* minimum of 3 */
	    printf("Warning: '-p %d' is too small; using %d instead\n",
		   lwps, 3);
	    lwps = 3;
	}
    }

#ifndef AFS_NT40_ENV
    if (cmd_OptionPresent(opts, OPT_syslog)) {
	serverLogSyslog = 1;
	cmd_OptionAsInt(opts, OPT_syslog, &serverLogSyslogFacility);
    }
#endif

    /* rx options */
    if (cmd_OptionPresent(opts, OPT_peer))
	rx_enablePeerRPCStats();

    if (cmd_OptionPresent(opts, OPT_process))
	rx_enableProcessRPCStats();

    cmd_OptionAsFlag(opts, OPT_rxbind, &rxBind);

    cmd_OptionAsInt(opts, OPT_rxmaxmtu, &rxMaxMTU);

    /* rxkad options */
    cmd_OptionAsFlag(opts, OPT_dotted, &rxkadDisableDotCheck);

    cmd_FreeOptions(&opts);

    if (auditFileName) {
	osi_audit_file(auditFileName);
	osi_audit(PTS_StartEvent, 0, AUD_END);
    }

#ifndef AFS_NT40_ENV
    serverLogSyslogTag = "ptserver";
#endif
    OpenLog(logFile);	/* set up logging */
    SetupLogSignals();

    prdir = afsconf_Open(configDir);
    if (!prdir) {
	fprintf(stderr, "ptserver: can't open configuration directory.\n");
	PT_EXIT(1);
    }
    if (afsconf_GetNoAuthFlag(prdir))
	printf("ptserver: running unauthenticated\n");

#ifdef AFS_NT40_ENV
    /* initialize winsock */
    if (afs_winsockInit() < 0) {
	ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);

	fprintf(stderr, "ptserver: couldn't initialize winsock. \n");
	PT_EXIT(1);
    }
#endif
    /* get this host */
    gethostname(hostname, sizeof(hostname));
    th = gethostbyname(hostname);
    if (!th) {
	fprintf(stderr, "ptserver: couldn't get address of this host.\n");
	PT_EXIT(1);
    }
    memcpy(&myHost, th->h_addr, sizeof(afs_uint32));

    /* get list of servers */
    code =
	afsconf_GetExtendedCellInfo(prdir, NULL, "afsprot", &info, clones);
    if (code) {
	afs_com_err(whoami, code, "Couldn't get server list");
	PT_EXIT(2);
    }

    /* initialize audit user check */
    osi_audit_set_user_check(prdir, pr_IsLocalRealmMatch);

    /* initialize ubik */
    ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate, prdir);
    ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects,
				afsconf_CheckAuth, prdir);

    /* The max needed is when deleting an entry.  A full CoEntry deletion
     * required removal from 39 entries.  Each of which may refers to the entry
     * being deleted in one of its CoEntries.  If a CoEntry is freed its
     * predecessor CoEntry will be modified as well.  Any freed blocks also
     * modifies the database header.  Counting the entry being deleted and its
     * CoEntry this adds up to as much as 1+1+39*3 = 119.  If all these entries
     * and the header are in separate Ubik buffers then 120 buffers may be
     * required. */
    ubik_nBuffers = 120 + /*fudge */ 40;

    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];
	    /* the following call is idempotent so if/when it gets called
	     * again by the ubik init stuff, it doesn't really matter
	     * -- klm
	     */
	    rx_InitHost(host, htons(AFSCONF_PROTPORT));
	}
    }

    /* Disable jumbograms */
    rx_SetNoJumbo();

    if (rxMaxMTU != -1) {
	if (rx_SetMaxMTU(rxMaxMTU) != 0) {
	    printf("rxMaxMTU %d is invalid\n", rxMaxMTU);
	    PT_EXIT(1);
	}
    }

    code =
	ubik_ServerInitByInfo(myHost, htons(AFSCONF_PROTPORT), &info, clones,
			      pr_dbaseName, &dbase);
    if (code) {
	afs_com_err(whoami, code, "Ubik init failed");
	PT_EXIT(2);
    }

#if defined(SUPERGROUPS)
    pt_hook_write();
#endif

    afsconf_BuildServerSecurityObjects(prdir, &securityClasses, &numClasses);

    tservice =
	rx_NewServiceHost(host, 0, PRSRV, "Protection Server", securityClasses,
		          numClasses, PR_ExecuteRequest);
    if (tservice == (struct rx_service *)0) {
	fprintf(stderr, "ptserver: Could not create new rx service.\n");
	PT_EXIT(3);
    }
    rx_SetMinProcs(tservice, 2);
    rx_SetMaxProcs(tservice, lwps);
    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);
    if (tservice == (struct rx_service *)0) {
	fprintf(stderr, "ptserver: Could not create new rx service.\n");
	PT_EXIT(3);
    }
    rx_SetMinProcs(tservice, 2);
    rx_SetMaxProcs(tservice, 4);

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

    LogCommandLine(argc, argv, "ptserver",
#if defined(SUPERGROUPS)
		   "1.1",
#else
		   "1.0",
#endif
		   "Starting AFS", FSLog);

    rx_StartServer(1);
    osi_audit(PTS_FinishEvent, -1, AUD_END);
    exit(0);
}
Example #28
0
static int
WorkerBee(struct cmd_syndesc *as, void *arock)
{
    afs_int32 code;
    char *dbFile;
    char *outFile;
    afs_int32 index;
    struct stat info;
    struct kaheader header;
    int nentries, i, j, count;
    int *entrys;
    struct kaentry entry;

    dbFile = as->parms[0].items->data;	/* -database */
    listuheader = (as->parms[1].items ? 1 : 0);	/* -uheader  */
    listkheader = (as->parms[2].items ? 1 : 0);	/* -kheader  */
    listentries = (as->parms[3].items ? 1 : 0);	/* -entries  */
    verbose = (as->parms[4].items ? 1 : 0);	/* -verbose  */
    outFile = (as->parms[5].items ? as->parms[5].items->data : NULL);	/* -rebuild  */

    if (outFile) {
	out = fopen(outFile, "w");
	if (!out) {
	    afs_com_err(whoami, errno, "opening output file %s", outFile);
	    exit(7);
	}
    } else
	out = 0;

    fd = open(dbFile, O_RDONLY, 0);
    if (fd < 0) {
	afs_com_err(whoami, errno, "opening database file %s", dbFile);
	exit(6);
    }
    code = fstat(fd, &info);
    if (code) {
	afs_com_err(whoami, errno, "stat'ing file %s", dbFile);
	exit(6);
    }
    if ((info.st_size - UBIK_HEADERSIZE) % UBIK_BUFFERSIZE)
	fprintf(stderr,
		"DATABASE SIZE INCONSISTENT: was %d, should be (n*%d + %d), for integral n\n",
		(int) info.st_size, UBIK_BUFFERSIZE, UBIK_HEADERSIZE);

    readUbikHeader();

    readDB(0, &header, sizeof(header));
    code = CheckHeader(&header);
    if (listkheader)
	PrintHeader(&header);

    nentries =
	(info.st_size -
	 (UBIK_HEADERSIZE + header.headerSize)) / sizeof(struct kaentry);
    entrys = calloc(nentries, sizeof(int));

    for (i = 0, index = sizeof(header); i < nentries;
	 i++, index += sizeof(struct kaentry)) {
	readDB(index, &entry, sizeof(entry));

	if (index >= header.eofPtr) {
	    entrys[i] |= 0x8;
	} else if (listentries) {
	    PrintEntry(index, &entry);
	}

	if (entry.flags & KAFNORMAL) {
	    entrys[i] |= 0x1;	/* user entry */

	    if (strlen(entry.userID.name) == 0) {
		if (verbose)
		    printf("Entry %d has zero length name\n", i);
		continue;
	    }
	    if (!DES_check_key_parity(ktc_to_cblock(&entry.key))
		|| DES_is_weak_key(ktc_to_cblock(&entry.key))) {
		fprintf(stderr, "Entry %d, %s, has bad key\n", i,
			EntryName(&entry));
		continue;
	    }

	    if (out) {
		RebuildEntry(&entry);
	    }

	} else if (entry.flags & KAFFREE) {
	    entrys[i] |= 0x2;	/* free entry */

	} else if (entry.flags & KAFOLDKEYS) {
	    entrys[i] |= 0x4;	/* old keys block */
	    /* Should check the structure of the oldkeys block? */

	} else {
	    if (index < header.eofPtr) {
		fprintf(stderr, "Entry %d is unrecognizable\n", i);
	    }
	}
    }

    /* Follow the hash chains */
    for (j = 0; j < HASHSIZE; j++) {
	for (index = header.nameHash[j]; index; index = entry.next) {
	    readDB(index, &entry, sizeof(entry));

	    /* check to see if the name is hashed correctly */
	    i = NameHash(&entry);
	    if (i != j) {
		fprintf(stderr,
			"Entry %" AFS_SIZET_FMT ", %s, found in hash chain %d (should be %d)\n",
			((index -
			  sizeof(struct kaheader)) / sizeof(struct kaentry)),
			EntryName(&entry), j, i);
	    }

	    /* Is it on another hash chain or circular hash chain */
	    i = (index - header.headerSize) / sizeof(entry);
	    if (entrys[i] & 0x10) {
		fprintf(stderr,
			"Entry %d, %s, hash index %d, was found on another hash chain\n",
			i, EntryName(&entry), j);
		if (entry.next)
		    fprintf(stderr, "Skipping rest of hash chain %d\n", j);
		else
		    fprintf(stderr, "No next entry in hash chain %d\n", j);
		code++;
		break;
	    }
	    entrys[i] |= 0x10;	/* On hash chain */
	}
    }

    /* Follow the free pointers */
    count = 0;
    for (index = header.freePtr; index; index = entry.next) {
	readDB(index, &entry, sizeof(entry));

	/* Is it on another chain or circular free chain */
	i = (index - header.headerSize) / sizeof(entry);
	if (entrys[i] & 0x20) {
	    fprintf(stderr, "Entry %d, %s, already found on free chain\n", i,
		    EntryName(&entry));
	    fprintf(stderr, "Skipping rest of free chain\n");
	    code++;
	    break;
	}
	entrys[i] |= 0x20;	/* On free chain */

	count++;
    }
    if (verbose)
	printf("Found %d free entries\n", count);

    /* Follow the oldkey blocks */
    count = 0;
    for (index = header.kvnoPtr; index; index = entry.next) {
	readDB(index, &entry, sizeof(entry));

	/* Is it on another chain or circular free chain */
	i = (index - header.headerSize) / sizeof(entry);
	if (entrys[i] & 0x40) {
	    fprintf(stderr, "Entry %d, %s, already found on olkeys chain\n",
		    i, EntryName(&entry));
	    fprintf(stderr, "Skipping rest of oldkeys chain\n");
	    code++;
	    break;
	}
	entrys[i] |= 0x40;	/* On free chain */

	count++;
    }
    if (verbose)
	printf("Found %d oldkey blocks\n", count);

    /* Now recheck all the blocks and see if they are allocated correctly
     * 0x1 --> User Entry           0x10 --> On hash chain
     * 0x2 --> Free Entry           0x20 --> On Free chain
     * 0x4 --> OldKeys Entry        0x40 --> On Oldkeys chain
     * 0x8 --> Past EOF
     */
    for (i = 0; i < nentries; i++) {
	j = entrys[i];
	if (j & 0x1) {		/* user entry */
	    if (!(j & 0x10))
		badEntry(j, i);	/* on hash chain? */
	    else if (j & 0xee)
		badEntry(j, i);	/* anything else? */
	} else if (j & 0x2) {	/* free entry */
	    if (!(j & 0x20))
		badEntry(j, i);	/* on free chain? */
	    else if (j & 0xdd)
		badEntry(j, i);	/* anything else? */
	} else if (j & 0x4) {	/* oldkeys entry */
	    if (!(j & 0x40))
		badEntry(j, i);	/* on oldkeys chain? */
	    else if (j & 0xbb)
		badEntry(j, i);	/* anything else? */
	} else if (j & 0x8) {	/* past eof */
	    if (j & 0xf7)
		badEntry(j, i);	/* anything else? */
	} else
	    badEntry(j, i);	/* anything else? */
    }

    exit(code != 0);
}
Example #29
0
/* vldbClientInit
 *      Initialize a client for the vl ubik database.
 */
int
vldbClientInit(int noAuthFlag, int localauth, char *cellName,
	       struct ubik_client **cstruct,
	       time_t *expires)
{
    afs_int32 code = 0;
    struct afsconf_dir *acdir;
    struct rx_securityClass *sc;
    afs_int32 i, scIndex = RX_SECIDX_NULL;
    struct afsconf_cell info;
    struct rx_connection *serverconns[VLDB_MAXSERVERS];
    afsconf_secflags secFlags;
    const char *confdir;

    secFlags = parseSecFlags(noAuthFlag, localauth, &confdir);
    secFlags |= AFSCONF_SECOPTS_FALLBACK_NULL;

    /* This just preserves old behaviour of using the default cell when
     * passed an empty string */
    if (cellName && cellName[0] == '\0')
	cellName = NULL;

    /* Find out about the given cell */
    acdir = afsconf_Open(confdir);
    if (!acdir) {
	afs_com_err(whoami, 0, "Can't open configuration directory '%s'", confdir);
	ERROR(BC_NOCELLCONFIG);
    }

    code = afsconf_GetCellInfo(acdir, cellName, AFSCONF_VLDBSERVICE, &info);
    if (code) {
	afs_com_err(whoami, code, "; Can't find cell %s's hosts in %s",
		    cellName, acdir->cellservDB);
	ERROR(BC_NOCELLCONFIG);
    }

    code = afsconf_PickClientSecObj(acdir, secFlags, &info, cellName,
				    &sc, &scIndex, expires);
    if (code) {
	afs_com_err(whoami, code, "(configuring connection security)");
	ERROR(BC_NOCELLCONFIG);
    }
    if (scIndex == RX_SECIDX_NULL && !noAuthFlag)
	afs_com_err(whoami, 0, "Can't get tokens - running unauthenticated");

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

    if (info.numServers > VLDB_MAXSERVERS) {
	afs_com_err(whoami, 0,
		"Warning: %d VLDB servers exist for cell '%s', can only remember the first %d",
		info.numServers, cellName, VLDB_MAXSERVERS);
	info.numServers = VLDB_MAXSERVERS;
    }

    for (i = 0; i < info.numServers; i++)
	serverconns[i] =
	    rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
			     info.hostAddr[i].sin_port, USER_SERVICE_ID, sc,
			     scIndex);
    serverconns[i] = 0;

    *cstruct = 0;
    code = ubik_ClientInit(serverconns, cstruct);
    if (code) {
	afs_com_err(whoami, code, "; Can't initialize ubik connection to vldb");
	ERROR(code);
    }

  error_exit:
    if (acdir)
	afsconf_Close(acdir);
    return (code);
}
Example #30
0
afs_int32
uss_kauth_AddUser(char *a_user, char *a_passwd)
{				/*uss_kauth_AddUser */
#ifdef USS_KAUTH_DB
    static char rn[] = "uss_kauth_AddUser";	/*Routine name */
#endif
    struct ktc_encryptionKey ktc_key;
    EncryptionKey key;
    afs_int32 code;

    if (uss_SkipKaserver) {
	/*
	 * Don't talk to the kaserver; assume calls succeded and simply return.
	 * Amasingly people want to update it (most likely kerberos) themselves...
	 */
	if (uss_verbose)
	    printf
		("[Skip Kaserver option - Adding of user %s in Authentication DB not done]\n",
		 a_user);
	return 0;
    }


    /*
     * Make sure the module has been initialized before we start trying
     * to talk to AuthServers.
     */
    if (!initDone) {
	code = InitThisModule();
	if (code)
	    exit(code);
    }

    /*
     * Given the (unencrypted) password and cell, generate a key to
     * pass to the AuthServer.
     */
    ka_StringToKey(a_passwd, uss_Cell, &ktc_key);

    memcpy(&key, &ktc_key, sizeof(key)); /* XXX - we could just cast */

    if (!uss_DryRun) {
	if (uss_verbose)
	    fprintf(stderr, "Adding user '%s' to the Authentication DB\n",
		    a_user);

#ifdef USS_KAUTH_DB_INSTANCE
	fprintf(stderr,
		"%s: KAM_CreateUser: user='******', CreatorInstance='%s', %d bytes\n",
		rn, a_user, CreatorInstance, strlen(CreatorInstance));
#endif /* USS_KAUTH_DB_INSTANCE */
	code = ubik_KAM_CreateUser(uconn_kauthP, 0, a_user,
			           UserInstance,	/*set by CheckUsername() */
			 	   key);
	if (code) {
	    if (code == KAEXIST) {
		if (uss_verbose)
		    fprintf(stderr,
			    "%s: Warning: User '%s' already in Authentication DB\n",
			    uss_whoami, a_user);
	    } else {
		afs_com_err(uss_whoami, code,
			"while adding user '%s' to Authentication DB",
			a_user);
#ifdef USS_KAUTH_DB
		printf("%s: Error code from KAM_CreateUser: %d\n", rn, code);
#endif /* USS_KAUTH_DB */
		return (code);
	    }
	}			/*KAM_CreateUser failed */
    } /*Not a dry run */
    else
	fprintf(stderr,
		"\t[Dry run - user '%s' NOT added to Authentication DB]\n",
		a_user);

    return (0);

}				/*uss_kauth_AddUser */