/** * Returns the total number of PTS users, belonging to the cell denoted * by cellHandle, that are not in KAS. * * env the Java environment * cls the current Java class * cellHandle the handle of the cell to which the users belong * returns total number of users that are in PTS and not KAS */ JNIEXPORT jint JNICALL Java_org_openafs_jafs_Cell_getPtsOnlyUserCount (JNIEnv *env, jclass cls, jlong cellHandle) { afs_status_t ast; void *iterationId; kas_identity_p who = (kas_identity_p) malloc( sizeof(kas_identity_t) ); kas_principalEntry_t kasEntry; char *userName; int i = 0; if( !who ) { throwAFSException( env, JAFSADMNOMEM ); return -1; } if( !pts_UserListBegin( (void *) cellHandle, &iterationId, &ast ) ) { free( who ); throwAFSException( env, ast ); return -1; } userName = malloc( sizeof(char)*PTS_MAX_NAME_LEN); if( !userName ) { free( who ); throwAFSException( env, JAFSADMNOMEM ); return -1; } while ( pts_UserListNext( (void *) iterationId, userName, &ast ) ) { if( strcmp( userName, "anonymous" ) != 0 ) { // make sure the name is within the allowed bounds if( strlen( userName ) > KAS_MAX_NAME_LEN ) { free( who ); free( userName ); throwAFSException( env, ADMPTSUSERNAMETOOLONG ); return -1; } // if there is a kas entry, recurse internal_makeKasIdentity( userName, who ); if( !kas_PrincipalGet( (void *) cellHandle, NULL, who, &kasEntry, &ast ) ) i++; } } free( userName ); free( who ); if( ast != ADMITERATORDONE ) { throwAFSException( env, ast ); return -1; } return i; }
BOOL AfsAppLib_IsUserAdmin (UINT_PTR hCreds, LPTSTR pszUser) { #ifndef USE_KASERVER return TRUE; #else BOOL rc = FALSE; afs_status_t status; UINT_PTR idClient; if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0) { TCHAR szCell[ cchRESOURCE ]; TCHAR szUser[ cchRESOURCE ]; SYSTEMTIME stExpire; if (asc_CredentialsCrack (idClient, hCreds, szCell, szUser, &stExpire, (ULONG*)&status)) { ASID idCell; if (asc_CellOpen (idClient, hCreds, szCell, AFSADMSVR_SCOPE_USERS, &idCell, (ULONG*)&status)) { ASID idUser; if (asc_ObjectFind (idClient, idCell, TYPE_USER, pszUser, &idUser, (ULONG*)&status)) { ASOBJPROP Info; if (asc_ObjectPropertiesGet (idClient, GET_ALL_DATA, idCell, idUser, &Info, (ULONG*)&status)) { if (Info.u.UserProperties.fHaveKasInfo) { rc = Info.u.UserProperties.KASINFO.fIsAdmin; } } } asc_CellClose (idClient, idCell, (ULONG*)&status); } } } else if (OpenClientLibrary()) { if (OpenKasLibrary()) { char szUserA[ cchRESOURCE ], szUser2A[ cchRESOURCE ]; char szCellA[ cchRESOURCE ]; unsigned long dateExpire; int fHasKasToken; if (afsclient_TokenQuery (hCreds, &dateExpire, szUserA, szUser2A, szCellA, &fHasKasToken, (afs_status_p)&status)) { PVOID hCell; if (afsclient_CellOpen (szCellA, hCreds, &hCell, &status)) { kas_identity_t Identity; memset (&Identity, 0x00, sizeof(Identity)); CopyStringToAnsi (Identity.principal, pszUser); kas_principalEntry_t Entry; if (kas_PrincipalGet (hCell, NULL, &Identity, &Entry, &status)) { if (Entry.adminSetting == KAS_ADMIN) rc = TRUE; } afsclient_CellClose (hCell, (afs_status_p)&status); } } CloseKasLibrary(); } CloseClientLibrary(); } return rc; #endif /* USE_KASERVER */ }
/** * Renames the given user. Does not update the info fields of the kas entry * -- the calling code is responsible for that. * * env the Java environment * cls the current Java class * cellHandle the handle of the cell to which the user belongs * joldName the name of the user to rename * jnewName the new name for the user */ JNIEXPORT void JNICALL Java_org_openafs_jafs_User_rename (JNIEnv *env, jclass cls, jlong cellHandle, jstring joldName, jstring jnewName) { const char *oldName; const char *newName; kas_identity_p whoOld = (kas_identity_p) malloc( sizeof(kas_identity_t) ); kas_identity_p whoNew = (kas_identity_p) malloc( sizeof(kas_identity_t) ); kas_principalEntry_t kasEntry; pts_UserEntry_t ptsEntry; afs_status_t ast; int kas; if( !whoOld || !whoNew ) { if( whoOld ) { free( whoOld ); } if( whoNew ) { free( whoNew ); } throwAFSException( env, JAFSADMNOMEM ); return; } if( joldName != NULL ) { oldName = (*env)->GetStringUTFChars(env, joldName, 0); if( !oldName ) { throwAFSException( env, JAFSADMNOMEM ); return; } } else { oldName = NULL; } if( jnewName != NULL ) { newName = (*env)->GetStringUTFChars(env, jnewName, 0); if( !newName ) { if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } throwAFSException( env, JAFSADMNOMEM ); return; } } else { newName = NULL; } // make sure the names are within the allowed bounds if( oldName != NULL && strlen( oldName ) > KAS_MAX_NAME_LEN ) { free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } throwAFSException( env, ADMPTSUSERNAMETOOLONG ); return; } if( newName != NULL && strlen( newName ) > KAS_MAX_NAME_LEN ) { free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } throwAFSException( env, ADMPTSUSERNAMETOOLONG ); return; } if( oldName != NULL ) { internal_makeKasIdentity( oldName, whoOld ); } if( newName != NULL ) { internal_makeKasIdentity( newName, whoNew ); } // retrieve the old kas info if( !kas_PrincipalGet( (void *) cellHandle, NULL, whoOld, &kasEntry, &ast ) ) { if( ast != KANOENT ) { free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } throwAFSException( env, ast ); return; } else { kas = FALSE; } } else { kas = TRUE; } if( kas ) { // create a new kas entry // temporarily set the password equal to the new name if (!kas_PrincipalCreate( (void *) cellHandle, NULL, whoNew, newName, &ast ) ) { free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } throwAFSException( env, ast ); return; } // set the password ast = 0; // For some reason kas_PrincipalKeySet doesn't set the return code // correctly. It always returns 0. // So instead of checking the return code, we see if there's an // error in the status variable. kas_PrincipalKeySet( (void *) cellHandle, NULL, whoNew, 0, &(kasEntry.key), &ast ); if( ast ) { afs_status_t ast_kd; kas_PrincipalDelete( (void *) cellHandle, NULL, whoNew, &ast_kd ); free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } throwAFSException( env, ast ); return; } } // rename the pts entry if( !pts_UserRename( (void *) cellHandle, oldName, newName, &ast ) ) { // throw exception if there was no such pts user only if // there was also no such kas user if( (ast == ADMPTSFAILEDNAMETRANSLATE && !kas ) || ast != ADMPTSFAILEDNAMETRANSLATE ) { afs_status_t ast_kd; if( kas ) { kas_PrincipalDelete( (void *) cellHandle, NULL, whoNew, &ast_kd ); } free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } throwAFSException( env, ast ); return; } } if( kas ) { // delete the old kas entry if( !kas_PrincipalDelete( (void *) cellHandle, NULL, whoOld, &ast ) ) { free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } throwAFSException( env, ast ); return; } } free( whoOld ); free( whoNew ); if( oldName != NULL ) { (*env)->ReleaseStringUTFChars(env, joldName, oldName); } if( newName != NULL ) { (*env)->ReleaseStringUTFChars(env, jnewName, newName); } }
/** * Retrieve the information for the specified user and populate the * given object * * env the Java environment * cellHandle the handle of the cell to which the user belongs * name the name of the user for which to get the info * user the User object to populate with the info */ void getUserInfoChar (JNIEnv *env, void *cellHandle, const char *name, jobject user) { jstring jowner; jstring jcreator; jstring jlastModName; jstring jencryptionKey; jboolean pts; jboolean kas; pts_UserEntry_t ptsEntry; afs_status_t ast; kas_identity_p who = (kas_identity_p) malloc( sizeof(kas_identity_t) ); kas_principalEntry_t kasEntry; unsigned int lockedUntil; if( !who ) { throwAFSException( env, JAFSADMNOMEM ); return; } // make sure the name is within the allowed bounds if( name != NULL && strlen( name ) > KAS_MAX_NAME_LEN ) { free( who ); throwAFSException( env, ADMPTSUSERNAMETOOLONG ); return; } if( name != NULL ) { internal_makeKasIdentity( name, who ); } // get all the field ids, if you haven't done so already if( userCls == 0 ) { internal_getUserClass( env, user ); } // get the pts entry if ( !pts_UserGet( cellHandle, name, &ptsEntry, &ast ) ) { // if the user has no pts ptsEntry if( ast == ADMPTSFAILEDNAMETRANSLATE ) { pts = FALSE; } else { free( who ); throwAFSException( env, ast ); return; } } else { pts = TRUE; } // get the kas entry if( !kas_PrincipalGet( cellHandle, NULL, who, &kasEntry, &ast ) ) { // no kas entry if( ast == KANOENT ) { if( !pts ) { free( who ); throwAFSException( env, ast ); return; } else { kas = FALSE; } // other } else { free( who ); throwAFSException( env, ast ); return; } } else { kas = TRUE; } // get the lock status if( kas && !kas_PrincipalLockStatusGet( cellHandle, NULL, who, &lockedUntil, &ast ) ) { free( who ); throwAFSException( env, ast ); return; } (*env)->SetBooleanField(env, user, user_ptsField, pts); (*env)->SetBooleanField(env, user, user_kasField, kas); // set the pts fields if( pts ) { (*env)->SetIntField(env, user, user_nameUidField, ptsEntry.nameUid); (*env)->SetIntField(env, user, user_ownerUidField, ptsEntry.ownerUid); (*env)->SetIntField(env, user, user_creatorUidField, ptsEntry.creatorUid); (*env)->SetIntField(env, user, user_groupCreationQuotaField, ptsEntry.groupCreationQuota); (*env)->SetIntField(env, user, user_groupMembershipCountField, ptsEntry.groupMembershipCount); if( ptsEntry.listStatus == PTS_USER_OWNER_ACCESS ) { (*env)->SetIntField(env, user, user_listStatusField, org_openafs_jafs_User_USER_OWNER_ACCESS); } else { (*env)->SetIntField(env, user, user_listStatusField, org_openafs_jafs_User_USER_ANYUSER_ACCESS); } if( ptsEntry.listGroupsOwned == PTS_USER_OWNER_ACCESS ) { (*env)->SetIntField(env, user, user_listGroupsOwnedField, org_openafs_jafs_User_USER_OWNER_ACCESS); } else { (*env)->SetIntField(env, user, user_listGroupsOwnedField, org_openafs_jafs_User_USER_ANYUSER_ACCESS); } if( ptsEntry.listMembership == PTS_USER_OWNER_ACCESS ) { (*env)->SetIntField(env, user, user_listMembershipField, org_openafs_jafs_User_USER_OWNER_ACCESS); } else { (*env)->SetIntField(env, user, user_listMembershipField, org_openafs_jafs_User_USER_ANYUSER_ACCESS); } jowner = (*env)->NewStringUTF(env, ptsEntry.owner); jcreator = (*env)->NewStringUTF(env, ptsEntry.creator); (*env)->SetObjectField(env, user, user_ownerField, jowner); (*env)->SetObjectField(env, user, user_creatorField, jcreator); } // set the kas fields if( kas ) { char *convertedKey; int i; if( kasEntry.adminSetting == KAS_ADMIN ) { (*env)->SetIntField(env, user, user_adminSettingField, org_openafs_jafs_User_ADMIN); } else { (*env)->SetIntField(env, user, user_adminSettingField, org_openafs_jafs_User_NO_ADMIN); } if( kasEntry.tgsSetting == TGS ) { (*env)->SetIntField(env, user, user_tgsSettingField, org_openafs_jafs_User_GRANT_TICKETS); } else { (*env)->SetIntField(env, user, user_tgsSettingField, org_openafs_jafs_User_NO_GRANT_TICKETS); } if( kasEntry.encSetting != NO_ENCRYPT ) { (*env)->SetIntField(env, user, user_encSettingField, org_openafs_jafs_User_ENCRYPT); } else { (*env)->SetIntField(env, user, user_encSettingField, org_openafs_jafs_User_NO_ENCRYPT); } if( kasEntry.cpwSetting == CHANGE_PASSWORD ) { (*env)->SetIntField(env, user, user_cpwSettingField, org_openafs_jafs_User_CHANGE_PASSWORD); } else { (*env)->SetIntField(env, user, user_cpwSettingField, org_openafs_jafs_User_NO_CHANGE_PASSWORD); } if( kasEntry.rpwSetting == REUSE_PASSWORD ) { (*env)->SetIntField(env, user, user_rpwSettingField, org_openafs_jafs_User_REUSE_PASSWORD); } else { (*env)->SetIntField(env, user, user_rpwSettingField, org_openafs_jafs_User_NO_REUSE_PASSWORD); } (*env)->SetIntField(env, user, user_userExpirationField, kasEntry.userExpiration); (*env)->SetIntField(env, user, user_lastModTimeField, kasEntry.lastModTime); (*env)->SetIntField(env, user, user_lastChangePasswordTimeField, kasEntry.lastChangePasswordTime); (*env)->SetIntField(env, user, user_maxTicketLifetimeField, kasEntry.maxTicketLifetime); (*env)->SetIntField(env, user, user_keyVersionField, kasEntry.keyVersion); (*env)->SetLongField(env, user, user_keyCheckSumField, (unsigned int) kasEntry.keyCheckSum); (*env)->SetIntField(env, user, user_daysToPasswordExpireField, kasEntry.daysToPasswordExpire); (*env)->SetIntField(env, user, user_failLoginCountField, kasEntry.failLoginCount); (*env)->SetIntField(env, user, user_lockTimeField, kasEntry.lockTime); (*env)->SetIntField(env, user, user_lockedUntilField, lockedUntil); jlastModName = (*env)->NewStringUTF(env, kasEntry.lastModPrincipal.principal); (*env)->SetObjectField(env, user, user_lastModNameField, jlastModName); convertedKey = (char *) malloc( sizeof(char *)* (sizeof(kasEntry.key.key)*4+1) ); if( !convertedKey ) { throwAFSException( env, JAFSADMNOMEM ); return; } for( i = 0; i < sizeof(kasEntry.key.key); i++ ) { sprintf( &(convertedKey[i*4]), "\\%0.3o", kasEntry.key.key[i] ); } jencryptionKey = (*env)->NewStringUTF(env, convertedKey); (*env)->SetObjectField(env, user, user_encryptionKeyField, jencryptionKey); free( convertedKey ); } free(who); }
/** * Fills the next pts user (who does not have a kas entry) object of * the cell. Returns 0 if there are no more users, != 0 otherwise. * * env the Java environment * cls the current Java class * cellHandle the handle of the cell to which the users belong * iterationId the iteration ID of this iteration * juserObject a User object to be populated with the values of * the next pts (with no kas) user * returns 0 if there are no more users, != 0 otherwise */ JNIEXPORT jint JNICALL Java_org_openafs_jafs_Cell_getPtsOnlyUsersNext (JNIEnv *env, jclass cls, jlong cellHandle, jlong iterationId, jobject juserObject ) { kas_identity_p who = (kas_identity_p) malloc( sizeof(kas_identity_t) ); kas_principalEntry_t kasEntry; afs_status_t ast; char *userName; jstring juser; if( !who ) { throwAFSException( env, JAFSADMNOMEM ); return 0; } userName = malloc( sizeof(char)*PTS_MAX_NAME_LEN); if( !userName ) { free( who ); throwAFSException( env, JAFSADMNOMEM ); return 0; } while( 1 ) { if( !pts_UserListNext( (void *) iterationId, userName, &ast ) ) { free( userName ); free( who ); if( ast == ADMITERATORDONE ) { return 0; } else { throwAFSException( env, ast ); return 0; } } if( strcmp( userName, "anonymous" ) == 0 ) { continue; } // make sure the name is within the allowed bounds if( strlen( userName ) > KAS_MAX_NAME_LEN ) { free( userName ); free( who ); throwAFSException( env, ADMPTSUSERNAMETOOLONG ); return 0; } if( userCls == 0 ) { internal_getUserClass( env, juserObject ); } // if there is a kas entry, recurse internal_makeKasIdentity( userName, who ); if( kas_PrincipalGet( (void *) cellHandle, NULL, who, &kasEntry, &ast ) ) { continue; } juser = (*env)->NewStringUTF(env, userName); (*env)->SetObjectField(env, juserObject, user_nameField, juser); getUserInfoChar( env, (void *) cellHandle, userName, juserObject ); (*env)->SetBooleanField( env, juserObject, user_cachedInfoField, TRUE ); free( who ); free( userName ); return 1; } }
/* * cfg_HostSetAfsPrincipal() -- Put AFS server principal (afs) key in * host's KeyFile; principal is created if it does not exist. * * If first server host in cell, passwd must be initial password for * the afs principal; the afs principal is created. * * If additional server host, passwd can be specified or NULL; the * afs principal must already exist by definition. If passwd is NULL * then an attempt is made to fetch the afs key. If the key fetch fails * because pre 3.5 database servers are in use (which will only return a * key checksum) then the function fails with a return status of * ADMCFGAFSKEYNOTAVAILABLE; in this case the function should be called * again with passwd specified. If passwd is specified (not NULL) but the * password key fails a checksum comparison with the current afs key * then the function fails with a return status of ADMCFGAFSPASSWDINVALID. * * ASSUMPTIONS: Client configured and BOS server started; if first host in * cell then Authentication server must be started as well. */ int ADMINAPI cfg_HostSetAfsPrincipal(void *hostHandle, /* host config handle */ short isFirst, /* first server in cell flag */ const char *passwd, /* afs initial password */ afs_status_p st) { /* completion status */ int rc = 1; afs_status_t tst2, tst = 0; cfg_host_p cfg_host = (cfg_host_p) hostHandle; /* validate parameters */ if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) { tst = tst2; } else if ((isFirst && passwd == NULL) || (passwd != NULL && *passwd == '\0')) { tst = ADMCFGPASSWDNULL; } /* put afs key in host's KeyFile */ if (tst == 0) { kas_identity_t afsIdentity; kas_encryptionKey_t afsKey; int afsKvno = 0; strcpy(afsIdentity.principal, "afs"); afsIdentity.instance[0] = '\0'; if (isFirst) { /* create afs principal */ if (!kas_PrincipalCreate (cfg_host->cellHandle, NULL, &afsIdentity, passwd, &tst2) && tst2 != KAEXIST) { /* failed to create principal (and not because existed) */ tst = tst2; } } if (tst == 0) { /* retrive afs principal information to verify or obtain key */ kas_principalEntry_t afsEntry; if (!kas_PrincipalGet (cfg_host->cellHandle, NULL, &afsIdentity, &afsEntry, &tst2)) { tst = tst2; } else { if (passwd != NULL) { /* password given; form key and verify as most recent */ kas_encryptionKey_t passwdKey; unsigned int passwdKeyCksum; if (!kas_StringToKey (cfg_host->cellName, passwd, &passwdKey, &tst2) || !kas_KeyCheckSum(&passwdKey, &passwdKeyCksum, &tst2)) { /* failed to form key or key checksum */ tst = tst2; } else if (passwdKeyCksum != afsEntry.keyCheckSum) { /* passwd string does not generate most recent key; * check if passwd string embeds key directly. */ if (KasKeyEmbeddedInString(passwd, &passwdKey)) { /* passwd string embeds kas key */ if (!kas_KeyCheckSum (&passwdKey, &passwdKeyCksum, &tst2)) { tst = tst2; } else if (passwdKeyCksum != afsEntry.keyCheckSum) { /* passwd string does not embed valid key */ tst = ADMCFGAFSPASSWDINVALID; } } else { /* passwd string does NOT embed key */ tst = ADMCFGAFSPASSWDINVALID; } } if (tst == 0) { /* passwd seems to generate/embed most recent key */ afsKey = passwdKey; afsKvno = afsEntry.keyVersion; } } else { /* password NOT given; check if key retrieved since * pre 3.5 database servers only return key checksum */ if (KasKeyIsZero(&afsEntry.key)) { tst = ADMCFGAFSKEYNOTAVAILABLE; } else { afsKey = afsEntry.key; afsKvno = afsEntry.keyVersion; } } } } if (tst == 0) { /* add key to host's KeyFile; RPC must be unauthenticated; * bosserver is presumed to be in noauth mode. */ void *cellHandle, *bosHandle; if (!afsclient_NullCellOpen(&cellHandle, &tst2)) { tst = tst2; } else { if (!bos_ServerOpen (cellHandle, cfg_host->hostName, &bosHandle, &tst2)) { tst = tst2; } else { if (!bos_KeyCreate(bosHandle, afsKvno, &afsKey, &tst2) && tst2 != BZKEYINUSE) { /* failed to add key (and not because existed) */ tst = tst2; } if (!bos_ServerClose(bosHandle, &tst2)) { tst = tst2; } } if (!afsclient_CellClose(cellHandle, &tst2)) { tst = tst2; } } } } if (tst != 0) { rc = 0; } if (st != NULL) { *st = tst; } return rc; }