Add method to allow elevated privelege operations from Posix

This commit is contained in:
Will Hedgecock 2022-01-28 14:09:15 -06:00
parent 28c21ec4eb
commit bc2ec3e8c4
2 changed files with 19 additions and 2 deletions

View File

@ -2,7 +2,7 @@
* PosixHelperFunctions.c
*
* Created on: Mar 10, 2015
* Last Updated on: Jan 25, 2022
* Last Updated on: Jan 28, 2022
* Author: Will Hedgecock
*
* Copyright (C) 2012-2022 Fazecast, Inc.
@ -1652,17 +1652,25 @@ int verifyAndSetUserPortGroup(const char *portFile)
}
// Attempt to add the user to the group that owns the port
char *addUserToGroupCmd = (char*)malloc(256);
if (!userPartOfPortGroup)
{
struct group *portGroup;
struct passwd *userDetails;
if ((portGroup = getgrgid(fileStats.st_gid)) && (userDetails = getpwuid(geteuid())))
{
char *addUserToGroupCmd = (char*)malloc(256);
snprintf(addUserToGroupCmd, 256, "sudo usermod -a -G %s %s", portGroup->gr_name, userDetails->pw_name);
userCanAccess = (system(addUserToGroupCmd) == 0);
}
}
// Attempt to enable all read/write port permissions
snprintf(addUserToGroupCmd, 256, "sudo chmod 666 %s", portFile);
userCanAccess = (system(addUserToGroupCmd) == 0) || userCanAccess;
// Clean up memory
free(addUserToGroupCmd);
free(userGroups);
}
// Return whether the user can currently access the serial port

View File

@ -65,6 +65,7 @@ jfieldID flowControlField;
jfieldID sendDeviceQueueSizeField;
jfieldID receiveDeviceQueueSizeField;
jfieldID disableExclusiveLockField;
jfieldID requestElevatedPermissionsField;
jfieldID rs485ModeField;
jfieldID rs485ActiveHighField;
jfieldID rs485EnableTerminationField;
@ -312,6 +313,8 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
if (checkJniError(env, __LINE__ - 1)) return;
disableExclusiveLockField = (*env)->GetFieldID(env, serialCommClass, "disableExclusiveLock", "Z");
if (checkJniError(env, __LINE__ - 1)) return;
requestElevatedPermissionsField = (*env)->GetFieldID(env, serialCommClass, "requestElevatedPermissions", "Z");
if (checkJniError(env, __LINE__ - 1)) return;
rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
if (checkJniError(env, __LINE__ - 1)) return;
rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z");
@ -406,6 +409,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char disableExclusiveLock = (*env)->GetBooleanField(env, obj, disableExclusiveLockField);
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char requestElevatedPermissions = (*env)->GetBooleanField(env, obj, requestElevatedPermissionsField);
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char disableAutoConfig = (*env)->GetBooleanField(env, obj, disableConfigField);
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char autoFlushIOBuffers = (*env)->GetBooleanField(env, obj, autoFlushIOBuffersField);
@ -427,6 +432,10 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
return 0;
}
// Fix user permissions so that they can open the port, if allowed
if (requestElevatedPermissions)
verifyAndSetUserPortGroup(portName);
// Try to open the serial port with read/write access
port->errorLineNumber = lastErrorLineNumber = __LINE__ + 1;
if ((port->handle = open(portName, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC)) > 0)