Пример #1
0
int
sudo_afs_verify(struct passwd *pw, char *pass, sudo_auth *auth)
{
    struct ktc_encryptionKey afs_key;
    struct ktc_token afs_token;
    debug_decl(sudo_afs_verify, SUDO_DEBUG_AUTH)

    /* Try to just check the password */
    ka_StringToKey(pass, NULL, &afs_key);
    if (ka_GetAdminToken(pw->pw_name,		/* name */
			 NULL,			/* instance */
			 NULL,			/* realm */
			 &afs_key,		/* key (contains password) */
			 0,			/* lifetime */
			 &afs_token,		/* token */
			 0) == 0)		/* new */
	debug_return_int(AUTH_SUCCESS);

    /* Fall back on old method XXX - needed? */
    setpag();
    if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION+KA_USERAUTH_DOSETPAG,
				   pw->pw_name,	/* name */
				   NULL,	/* instance */
				   NULL,	/* realm */
				   pass,	/* password */
				   0,		/* lifetime */
				   NULL,	/* expiration ptr (unused) */
				   0,		/* spare */
				   NULL) == 0)	/* reason */
	debug_return_int(AUTH_SUCCESS);

    debug_return_int(AUTH_FAILURE);
}
Пример #2
0
struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
{
  char *reason;
				/* faster validation for POP servers */
  if (!strcmp ((char *) mail_parameters (NIL,GET_SERVICENAME,NIL),"pop")) {
    struct ktc_encryptionKey key;
    struct ktc_token token;
				/* just check the password */
    ka_StringToKey (pass,NIL,&key);
    if (ka_GetAdminToken (pw->pw_name,"","",&key,600,&token,1)) return NIL;
  }
				/* check password and get AFS token */
  else if (ka_UserAuthenticateGeneral
	   (KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,pw->pw_name,NIL,NIL,
	    pass,0,0,0,&reason)) return NIL;
				/* arm hook to delete credentials */
  mail_parameters (NIL,SET_LOGOUTHOOK,(void *) checkpw_cleanup);
  return pw;
}
Пример #3
0
afs_int32
ka_ReadPassword(char *prompt, int verify, char *cell,
		struct ktc_encryptionKey *key)
{
    char password[BUFSIZ];
    afs_int32 code;

    LOCK_GLOBAL_MUTEX;
    memset(key, 0, sizeof(struct ktc_encryptionKey));
    code = UI_UTIL_read_pw_string(password, sizeof(password), prompt, verify);
    if (code) {
	UNLOCK_GLOBAL_MUTEX;
	return KAREADPW;
    }
    if (strlen(password) == 0) {
	UNLOCK_GLOBAL_MUTEX;
	return KANULLPASSWORD;
    }
    ka_StringToKey(password, cell, key);
    UNLOCK_GLOBAL_MUTEX;
    return 0;
}
Пример #4
0
int
main(int argc, char **argv)
{
    struct afsconf_dir *tdir;
    afs_int32 code;

    if (argc == 1) {
	printf("bos_util: usage is 'bos_util <opcode> options, e.g.\n");
	printf("    bos_util add <kvno>\n");
	printf("    bos_util adddes <kvno>\n");
#ifdef KERBEROS
	printf("    bos_util srvtab2keyfile <kvno> <keyfile> <princ>\n");
#endif
	printf("    bos_util delete <kvno>\n");
	printf("    bos_util list\n");
	exit(1);
    }

    tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIR);
    if (!tdir) {
	printf("bos_util: can't initialize conf dir '%s'\n",
	       AFSDIR_SERVER_ETC_DIR);
	exit(1);
    }
    if (strcmp(argv[1], "add") == 0) {
	struct ktc_encryptionKey tkey;
	int kvno;
	char buf[BUFSIZ], ver[BUFSIZ];
	char *tcell = NULL;

	if (argc != 3) {
	    printf("bos_util add: usage is 'bos_util add <kvno>\n");
	    exit(1);
	}
	kvno = atoi(argv[2]);
	memset(&tkey, 0, sizeof(struct ktc_encryptionKey));

	/* prompt for key */
	code = des_read_pw_string(buf, sizeof(buf), "input key: ", 0);
	if (code || strlen(buf) == 0) {
	    printf("Bad key: \n");
	    exit(1);
	}
	code = des_read_pw_string(ver, sizeof(ver), "Retype input key: ", 0);
	if (code || strlen(ver) == 0) {
	    printf("Bad key: \n");
	    exit(1);
	}
	if (strcmp(ver, buf) != 0) {
	    printf("\nInput key mismatch\n");
	    exit(1);
	}
	ka_StringToKey(buf, tcell, &tkey);
	code = afsconf_AddKey(tdir, kvno, ktc_to_charptr(&tkey), 0);
	if (code) {
	    printf("bos_util: failed to set key, code %d.\n", code);
	    exit(1);
	}
    } else if (strcmp(argv[1], "adddes") == 0) {
	struct ktc_encryptionKey tkey;
	int kvno;
	afs_int32 code;
	char buf[BUFSIZ], ver[BUFSIZ];

	if (argc != 3) {
	    printf("bos_util adddes: usage is 'bos_util adddes <kvno>\n");
	    exit(1);
	}
	kvno = atoi(argv[2]);
	memset(&tkey, 0, sizeof(struct ktc_encryptionKey));

	/* prompt for key */
	code = des_read_pw_string(buf, sizeof(buf), "input key: ", 0);
	if (code || strlen(buf) == 0) {
	    printf("Bad key: \n");
	    exit(1);
	}
	code = des_read_pw_string(ver, sizeof(ver), "Retype input key: ", 0);
	if (code || strlen(ver) == 0) {
	    printf("Bad key: \n");
	    exit(1);
	}
	if (strcmp(ver, buf) != 0) {
	    printf("\nInput key mismatch\n");
	    exit(1);
	}
	des_string_to_key(buf, ktc_to_cblockptr(&tkey));
	code = afsconf_AddKey(tdir, kvno, ktc_to_charptr(&tkey), 0);
	if (code) {
	    printf("bos_util: failed to set key, code %d.\n", code);
	    exit(1);
	}
    }
#ifdef KERBEROS
    else if (strcmp(argv[1], "srvtab2keyfile") == 0) {
	char tkey[8], name[255], inst[255], realm[255];
	int kvno;
	if (argc != 5) {
	    printf
		("bos_util add: usage is 'bos_util srvtab2keyfile <kvno> <keyfile> <princ>\n");
	    exit(1);
	}
	kvno = atoi(argv[2]);
	bzero(tkey, sizeof(tkey));
	code = kname_parse(name, inst, realm, argv[4]);
	if (code != 0) {
	    printf("Invalid kerberos name\n");
	    exit(1);
	}
	code = read_service_key(name, inst, realm, kvno, argv[3], tkey);
	if (code != 0) {
	    printf("Can't find key in %s\n", argv[3]);
	    exit(1);
	}
	code = afsconf_AddKey(tdir, kvno, tkey, 0);
	if (code) {
	    printf("bos_util: failed to set key, code %d.\n", code);
	    exit(1);
	}
    }
#endif
    else if (strcmp(argv[1], "delete") == 0) {
	long kvno;
	if (argc != 3) {
	    printf("bos_util delete: usage is 'bos_util delete <kvno>\n");
	    exit(1);
	}
	kvno = atoi(argv[2]);
	code = afsconf_DeleteKey(tdir, kvno);
	if (code) {
	    printf("bos_util: failed to delete key %ld, (code %d)\n", kvno,
		   code);
	    exit(1);
	}
    } else if (strcmp(argv[1], "list") == 0) {
	struct afsconf_keys tkeys;
	int i;
	unsigned char tbuffer[9];

	code = afsconf_GetKeys(tdir, &tkeys);
	if (code) {
	    printf("bos_util: failed to get keys, code %d\n", code);
	    exit(1);
	}
	for (i = 0; i < tkeys.nkeys; i++) {
	    if (tkeys.key[i].kvno != -1) {
		int count;
		unsigned char x[8];
		memcpy(tbuffer, tkeys.key[i].key, 8);
		tbuffer[8] = 0;
		printf("kvno %4d: key is '%s' '", tkeys.key[i].kvno, tbuffer);
		strcpy((char *)x, (char *)tbuffer);
		for (count = 0; count < 8; count++)
		    printf("\\%03o", x[count]);
		printf("'\n");
	    }
	}
	printf("All done.\n");
    } else {
	printf
	    ("bos_util: unknown operation '%s', type 'bos_util' for assistance\n",
	     argv[1]);
	exit(1);
    }
    exit(0);
}
Пример #5
0
afs_int32
ka_UserAuthenticateGeneral(afs_int32 flags, char *name, char *instance,
			   char *realm, char *password, Date lifetime,
			   afs_int32 * password_expires,	/* days 'til, or don't change if not set */
			   afs_int32 spare2, char **reasonP)
{
    int remainingTime = 0;
    struct ktc_encryptionKey key;
    afs_int32 code, dosetpag = 0;

    if (reasonP)
	*reasonP = "";
    if ((flags & KA_USERAUTH_VERSION_MASK) != KA_USERAUTH_VERSION)
	return KAOLDINTERFACE;
    if ((strcmp(name, "root") == 0) && (instance == 0)) {
	if (reasonP)
	    *reasonP = "root is only authenticated locally";
	return KANOENT;
    }
    code = ka_Init(0);
    if (code)
	return code;

    ka_StringToKey(password, realm, &key);

/*
 * alarm is set by kpasswd only so ignore for
 * NT
 */

#ifndef AFS_NT40_ENV
    {				/* Rx uses timers, save to be safe */
	if (rx_socket) {
	    /* don't reset alarms, rx already running */
	    remainingTime = 0;
	} else
	    remainingTime = alarm(0);
    }
#endif

#if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && (!defined(AFS_XBSD_ENV) || defined(AFS_FBSD_ENV))
    /* handle smoothly the case where no AFS system calls exists (yet) */
    (void)signal(SIGSYS, SIG_IGN);
#endif
#ifdef	AFS_DECOSF_ENV
    (void)signal(SIGTRAP, SIG_IGN);
#endif /* AFS_DECOSF_ENV */
    if (instance == 0)
	instance = "";
    if (flags & KA_USERAUTH_ONLY_VERIFY) {
	code = ka_VerifyUserToken(name, instance, realm, &key);
	if (code == KABADREQUEST) {
	    DES_string_to_key(password, ktc_to_cblockptr(&key));
	    code = ka_VerifyUserToken(name, instance, realm, &key);
	}
    } else {
#ifdef AFS_DUX40_ENV
	if (flags & KA_USERAUTH_DOSETPAG)
	    afs_setpag();
#else
#if !defined(UKERNEL) && !defined(AFS_NT40_ENV)
	if (flags & KA_USERAUTH_DOSETPAG)
	    setpag();
#endif
#endif
	if (flags & KA_USERAUTH_DOSETPAG2)
	    dosetpag = 1;
#ifdef AFS_KERBEROS_ENV
	if ((flags & KA_USERAUTH_DOSETPAG) || dosetpag)
	    ktc_newpag();
#endif
	if (lifetime == 0)
	    lifetime = MAXKTCTICKETLIFETIME;
	code =
	    GetTickets(name, instance, realm, &key, lifetime,
		       password_expires, dosetpag);
	if (code == KABADREQUEST) {
	    DES_string_to_key(password, ktc_to_cblockptr(&key));
	    code =
		GetTickets(name, instance, realm, &key, lifetime,
			   password_expires, dosetpag);
	}
    }

#ifndef AFS_NT40_ENV
    if (remainingTime) {
	pr_End();
	rx_Finalize();
	alarm(remainingTime);	/* restore timer, if any */
    }
#endif

    if (code && reasonP)
	switch (code) {
	case KABADREQUEST:
	    *reasonP = "password was incorrect";
	    break;
	case KAUBIKCALL:
	    *reasonP = "Authentication Server was unavailable";
	    break;
	default:
	    *reasonP = (char *)afs_error_message(code);
	}
    return code;
}
Пример #6
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);
	}
    }
Пример #7
0
afs_int32
ka_UserAuthenticateGeneral2(afs_int32 flags, char *name, char *instance,
			    char *realm, char *password, char *smbname,
			    Date lifetime, afs_int32 * password_expiresP,
			    afs_int32 spare, char **reasonP)
{
    int code;
    struct ktc_encryptionKey key1, key2;
    char *ticket = NULL;
    int ticketLen;
    struct ktc_encryptionKey sessionKey;
    long kvno;
    long expirationTime;
    char fullRealm[256];
    char upperRealm[256];
    struct servent *sp;
    int ttl;

    struct ktc_principal server;
    struct ktc_principal client;
    struct ktc_token token;

    if (instance == NULL)
	instance = "";
    if (lifetime == 0)
	lifetime = MAXKTCTICKETLIFETIME;

    code = cm_SearchCellFile(realm, fullRealm, ka_AddHostProc, NULL);

#ifdef AFS_AFSDB_ENV
    if (code) {
	code =
	    cm_SearchCellByDNS(realm, fullRealm, &ttl, ka_AddHostProc, NULL);
    }
#endif
    if (code) {
	*reasonP = "specified realm is unknown";
	return (code);
    }

    strcpy(upperRealm, fullRealm);
    _strupr(upperRealm);

    /* encrypt password, both ways */
    ka_StringToKey(password, upperRealm, &key1);
    des_string_to_key(password, &key2);

    /* set port number */
    sp = getservbyname("kerberos", "udp");
    if (sp)
	krb_set_port(ntohs(sp->s_port));

    *reasonP = NULL;
    code =
	krb_get_in_tkt_ext(name, instance, upperRealm, "afs", "", lifetime,
			   &key1, &key2, &ticket, &ticketLen, &sessionKey,
			   &kvno, &expirationTime, reasonP);

    if (code && *reasonP == NULL)
	*reasonP = ka_MapKerberosError(code);

    if (code)
	return code;

    strcpy(server.name, "afs");
    strcpy(server.instance, "");
    strcpy(server.cell, fullRealm);

    /* Would like to use Vice ID's; using raw names for now. */
    strcpy(client.name, name);
    strcpy(client.instance, instance);
    strcpy(client.cell, upperRealm);
    if (smbname)
	strcpy(client.smbname, smbname);

    token.startTime = 0;	/* XXX */
    token.endTime = expirationTime;
    token.sessionKey = sessionKey;
    token.kvno = (short)kvno;
    token.ticketLen = ticketLen;
    memcpy(token.ticket, ticket, ticketLen);

    code =
	ktc_SetToken(&server, &token, &client,
		     (flags & KA_USERAUTH_AUTHENT_LOGON) ? AFS_SETTOK_LOGON :
		     0);
    if (code) {
	if (code == KTC_NOCM || code == KTC_NOCMRPC)
	    *reasonP = "AFS service may not have started";
	else if (code == KTC_RPC)
	    *reasonP = "RPC failure in AFS gateway";
	else if (code == KTC_NOCELL)
	    *reasonP = "unknown cell";
	else
	    *reasonP = "unknown error";
    }

    return code;
}
Пример #8
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);
}
Пример #9
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 */
Пример #10
0
afs_int32
InitThisModule(void)
{				/*InitThisModule */
#ifdef USS_KAUTH_DB
    static char rn[] = "uss_kauth:InitThisModule";
#endif
    afs_int32 code;
    char prompt[2 * MAXKTCNAMELEN + 20];
    char *reasonString, longPassBuff[1024], shortPassBuff[9];
    struct ktc_encryptionKey key;
    struct ktc_token token;
    struct ktc_principal Name, tok;

    /*
     * Only call this routine once.
     */
    if (initDone)
	return (0);


    /*
     * Pull out the caller's administrator token if they have one.
     */
    code =
	ka_GetAdminToken(0, 0, uss_Cell, 0, 10 * 60 * 60, &token,
			 0 /*new */ );
    if (code) {
	if (Pipe) {
	    strncpy(longPassBuff, getpipepass(), sizeof(longPassBuff));
	} else {
	    /*
	     * Nope, no admin tokens available.  Get the key based on the
	     * full password and try again.
	     */
	    sprintf(prompt, "Password for '%s", uss_AccountCreator);
	    if (CreatorInstance[0])
		sprintf(prompt + strlen(prompt), ".%s", CreatorInstance);
	    strcat(prompt, "': ");
	    code = ka_UserReadPassword(prompt,	/*Prompt to use */
				       longPassBuff,	/*Long pwd buffer */
				       sizeof(longPassBuff),	/*Size of above */
				       &reasonString);
	    if (code) {
		afs_com_err(uss_whoami, code, "while getting password ");
#ifdef USS_KAUTH_DB
		printf("%s: Error code from ka_UserReadPassword(): %d\n", rn,
		       code);
#endif /* USS_KAUTH_DB */
		return (code);
	    }
	}
	ka_StringToKey(longPassBuff, uss_Cell, &key);
	code =
	    ka_GetAdminToken(uss_AccountCreator, CreatorInstance, uss_Cell,
			     &key, 24 * 60 * 60, &token, 0 /*new */ );
	if (code) {
	    if ((code == KABADREQUEST) && (strlen(longPassBuff) > 8)) {
		/*
		 * The key we provided just doesn't work, yet we
		 * suspect that since the password is greater than 8
		 * chars, it might be the case that we really need
		 * to truncate the password to generate the appropriate
		 * key.
		 */
		afs_com_err(uss_whoami, code,
			"while getting administrator token (trying shortened password next...)");
#ifdef USS_KAUTH_DB
		printf("%s: Error code from ka_GetAdminToken: %d\n", rn,
		       code);
#endif /* USS_KAUTH_DB */
		strncpy(shortPassBuff, longPassBuff, 8);
		shortPassBuff[8] = 0;
		ka_StringToKey(shortPassBuff, uss_Cell, &key);
		code =
		    ka_GetAdminToken(uss_AccountCreator, CreatorInstance,
				     uss_Cell, &key, 24 * 60 * 60, &token,
				     0 /*new */ );
		if (code) {
		    afs_com_err(uss_whoami, code,
			    "while getting administrator token (possibly wrong password, or not an administrative account)");
#ifdef USS_KAUTH_DB
		    printf("%s: Error code from ka_GetAdminToken: %d\n", rn,
			   code);
#endif /* USS_KAUTH_DB */
		    return (code);
		} else {
		    /*
		     * The silly administrator has a long password!  Tell
		     * him or her off in a polite way.
		     */
		    printf
			("%s: Shortened password accepted by the Authentication Server\n",
			 uss_whoami);
		}
	    } /*Try a shorter password */
	    else {
		/*
		 * We failed to get an admin token, but the password is
		 * of a reasonable length, so we're just hosed.
		 */
		afs_com_err(uss_whoami, code,
			"while getting administrator token (possibly wrong password, or not an administrative account)");
#ifdef USS_KAUTH_DB
		printf("%s: Error code from ka_GetAdminToken: %d\n", rn,
		       code);
#endif /* USS_KAUTH_DB */
		return (code);
	    }			/*Even the shorter password didn't work */
	}			/*Key from given password didn't work */
    }

    /*First attempt to get admin token failed */
    /*
     * At this point, we have acquired an administrator token.  Let's
     * proceed to set up a connection to the AuthServer.
     */
#ifdef USS_KAUTH_DB_INSTANCE
    fprintf(stderr,
	    "%s: CreatorInstance after ka_GetAdminToken(): '%s', %d bytes\n",
	    rn, CreatorInstance, strlen(CreatorInstance));
#endif /* USS_KAUTH_DB_INSTANCE */

    /*
     * Set up the connection to the AuthServer read/write site.
     */
    code =
	ka_AuthServerConn(uss_Cell, KA_MAINTENANCE_SERVICE, &token,
			  &uconn_kauthP);
    if (code) {
	afs_com_err(uss_whoami, code,
		"while establishing Authentication Server connection");
#ifdef USS_KAUTH_DB
	printf("%s: Error code from ka_AuthServerConn: %d\n", rn, code);
#endif /* USS_KAUTH_DB */
	return (code);
    }

    if (uss_Administrator[0]) {
	/*
	 * We must check to see if we have local tokens for admin since he'll may do
	 * various pioctl or calls to protection server that require tokens. Remember
	 * to remove this tokens at the end of the program...
	 */
	strcpy(Name.name, "afs");
	Name.instance[0] = '\0';
	strncpy(Name.cell, uss_Cell, sizeof(Name.cell));
	if ((code =
	    ktc_GetToken(&Name, &token, sizeof(struct ktc_token), &tok))) {
	    code =
		ka_UserAuthenticateLife(0, uss_AccountCreator,
					CreatorInstance, uss_Cell,
					longPassBuff, 10 * 60 * 60,
					&reasonString);
	    if (!code)
		doUnlog = 1;
	}
    }

    /*
     * Declare our success.
     */
    initDone = 1;
    return (0);

}				/*InitThisModule */