Unified · Split
| @@ -74,9 +74,6 @@ namespace GSF.Console · 73 unmodified lines | ||
| 74 | 74 | |
| 75 | 75 | m_process.OutputDataReceived += m_process_OutputDataReceived; |
| 76 | 76 | m_process.ErrorDataReceived += m_process_ErrorDataReceived; |
| 77 | − | |
| 78 | − m_process.BeginOutputReadLine(); | |
| 79 | − m_process.BeginErrorReadLine(); | |
| 80 | 77 | } |
| 81 | 78 | |
| 82 | 79 | /// <summary> |
| @@ -170,6 +167,9 @@ namespace GSF.Console · 87 unmodified lines | ||
| 170 | 167 | { |
| 171 | 168 | m_process.Start(); |
| 172 | 169 | |
| 170 | + m_process.BeginOutputReadLine(); | |
| 171 | + m_process.BeginErrorReadLine(); | |
| 172 | + | |
| 173 | 173 | if (!m_process.WaitForExit(timeout)) |
| 174 | 174 | { |
| 175 | 175 | m_process.CancelOutputRead(); |
| @@ -183,12 +183,12 @@ namespace GSF.Console · 7 unmodified lines | ||
| 183 | 183 | |
| 184 | 184 | private void m_process_OutputDataReceived(object sender, DataReceivedEventArgs e) |
| 185 | 185 | { |
| 186 | − m_standardOutput.Append(e.Data); | |
| 186 | + m_standardOutput.AppendLine(e.Data); | |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | 189 | private void m_process_ErrorDataReceived(object sender, DataReceivedEventArgs e) |
| 190 | 190 | { |
| 191 | − m_standardError.Append(e.Data); | |
| 191 | + m_standardError.AppendLine(e.Data); | |
| 192 | 192 | } |
| 193 | 193 | |
| 194 | 194 | #endregion |
| @@ -21,6 +21,9 @@ · 20 unmodified lines | ||
| 21 | 21 | // |
| 22 | 22 | //****************************************************************************************************** |
| 23 | 23 | |
| 24 | +// Undefine to use internally linked unmanaged functions (e.g., when Mono hosted in gsf service) | |
| 25 | +#define USE_SHARED_OBJECT | |
| 26 | + | |
| 24 | 27 | using System; |
| 25 | 28 | using System.Collections; |
| 26 | 29 | using System.Collections.Generic; |
| @@ -44,6 +47,12 @@ namespace GSF.Identity · 17 unmodified lines | ||
| 44 | 47 | // Unix implementation of key UserInfo class elements |
| 45 | 48 | internal class UnixUserInfo : IUserInfo |
| 46 | 49 | { |
| 50 | +#if USE_SHARED_OBJECT | |
| 51 | + private const string IMPORT = "GSF.POSIX.so"; | |
| 52 | +#else | |
| 53 | + private const string IMPORT = "__Internal"; | |
| 54 | +#endif | |
| 55 | + | |
| 47 | 56 | #region [ Members ] |
| 48 | 57 | |
| 49 | 58 | // Nested Types |
| @@ -450,7 +459,7 @@ namespace GSF.Identity · 400 unmodified lines | ||
| 450 | 459 | if (!m_isLocalAccount) |
| 451 | 460 | return GetUserPropertyValueCollection("memberOf"); |
| 452 | 461 | |
| 453 | − return new string[0]; | |
| 462 | + return LocalGroups; | |
| 454 | 463 | } |
| 455 | 464 | } |
| 456 | 465 | |
| @@ -482,6 +491,9 @@ namespace GSF.Identity · 25 unmodified lines | ||
| 482 | 491 | if (string.IsNullOrWhiteSpace(userName)) |
| 483 | 492 | return m_parent.UserName; |
| 484 | 493 | |
| 494 | + if (userName.Contains(",")) | |
| 495 | + userName = userName.Split(',')[0]; | |
| 496 | + | |
| 485 | 497 | return userName; |
| 486 | 498 | } |
| 487 | 499 | } |
| @@ -1271,51 +1283,51 @@ namespace GSF.Identity · 783 unmodified lines | ||
| 1271 | 1283 | #endregion |
| 1272 | 1284 | |
| 1273 | 1285 | // AuthenticateUser function is PAM based, so it will support more than local users |
| 1274 | − [DllImport("GSF.POSIX.so")] | |
| 1286 | + [DllImport(IMPORT)] | |
| 1275 | 1287 | private static extern int AuthenticateUser(string userName, string password); |
| 1276 | 1288 | |
| 1277 | 1289 | // ChangeUserPassword function is PAM based, so it will support more than local users |
| 1278 | − [DllImport("GSF.POSIX.so")] | |
| 1290 | + [DllImport(IMPORT)] | |
| 1279 | 1291 | private static extern int ChangeUserPassword(string userName, string oldPassword, string newPassword); |
| 1280 | 1292 | |
| 1281 | − [DllImport("GSF.POSIX.so")] | |
| 1293 | + [DllImport(IMPORT)] | |
| 1282 | 1294 | private static extern int GetLocalUserID(string userName, out uint userID); |
| 1283 | 1295 | |
| 1284 | 1296 | // Preallocate outbound userName to 256 characters |
| 1285 | − [DllImport("GSF.POSIX.so")] | |
| 1297 | + [DllImport(IMPORT)] | |
| 1286 | 1298 | private static extern int GetLocalUserName(uint uid, StringBuilder userName); |
| 1287 | 1299 | |
| 1288 | 1300 | // Returns a char* that needs to marshaled to a .NET string |
| 1289 | − [DllImport("GSF.POSIX.so")] | |
| 1301 | + [DllImport(IMPORT)] | |
| 1290 | 1302 | private static extern IntPtr GetLocalUserGecos(string userName); |
| 1291 | 1303 | |
| 1292 | 1304 | // UserPasswordInformation structure contains only blittable types so it will be marshaled by reference |
| 1293 | − [DllImport("GSF.POSIX.so")] | |
| 1305 | + [DllImport(IMPORT)] | |
| 1294 | 1306 | private static extern int GetLocalUserPasswordInformation(string userName, UserPasswordInformation userPasswordInfo, out AccountStatus status); |
| 1295 | 1307 | |
| 1296 | − [DllImport("GSF.POSIX.so")] | |
| 1308 | + [DllImport(IMPORT)] | |
| 1297 | 1309 | private static extern int SetLocalUserPassword(string userName, string password, string salt); |
| 1298 | 1310 | |
| 1299 | 1311 | // Returns a char* that needs to be marshaled to a .NET string |
| 1300 | − [DllImport("GSF.POSIX.so")] | |
| 1312 | + [DllImport(IMPORT)] | |
| 1301 | 1313 | private static extern IntPtr GetPasswordHash(string password, string salt); |
| 1302 | 1314 | |
| 1303 | − [DllImport("GSF.POSIX.so")] | |
| 1315 | + [DllImport(IMPORT)] | |
| 1304 | 1316 | private static extern int GetLocalUserGroupCount(string userName); |
| 1305 | 1317 | |
| 1306 | 1318 | // Preallocate groupIDs as an unsigned integer array sized from GetLocalUserGroupCount |
| 1307 | − [DllImport("GSF.POSIX.so")] | |
| 1319 | + [DllImport(IMPORT)] | |
| 1308 | 1320 | private static extern int GetLocalUserGroupIDs(string userName, int groupCount, ref uint[] groupsIDs); |
| 1309 | 1321 | |
| 1310 | − [DllImport("GSF.POSIX.so")] | |
| 1322 | + [DllImport(IMPORT)] | |
| 1311 | 1323 | private static extern int GetLocalGroupID(string groupName, out uint groupID); |
| 1312 | 1324 | |
| 1313 | 1325 | // Preallocate outbound userName to 256 characters |
| 1314 | − [DllImport("GSF.POSIX.so")] | |
| 1326 | + [DllImport(IMPORT)] | |
| 1315 | 1327 | private static extern int GetLocalGroupName(uint uid, StringBuilder groupName); |
| 1316 | 1328 | |
| 1317 | 1329 | // Returns a char** that needs to be marshaled to a .NET string array |
| 1318 | − [DllImport("GSF.POSIX.so")] | |
| 1330 | + [DllImport(IMPORT)] | |
| 1319 | 1331 | private static extern IntPtr GetLocalGroupMembers(string groupName); |
| 1320 | 1332 | |
| 1321 | 1333 | #endregion |
| @@ -21,14 +21,23 @@ · 20 unmodified lines | ||
| 21 | 21 | // |
| 22 | 22 | //****************************************************************************************************** |
| 23 | 23 | |
| 24 | +// This will create a shared object for needed GSF functions | |
| 25 | + | |
| 24 | 26 | // Compiling for Linux: |
| 25 | 27 | // |
| 26 | −// Get PAM development libraries, e.g., for Ubuntu: apt-get install libpam0g-dev | |
| 28 | +// Get PAM development libraries, e.g., for Ubuntu: apt-get install libpam0g-dev | |
| 27 | 29 | // |
| 30 | +// To compile to an object library | |
| 28 | 31 | // gcc -c -Wall -Werror -fpic GSF.POSIX.c |
| 29 | −// gcc -shared -o GSF.POSIX.so GSF.POSIX.o -lpam -lpam_misc | |
| 32 | +// | |
| 33 | +// To compile as a shared object | |
| 34 | +// gcc -shared -o GSF.POSIX.so GSF.POSIX.o -lpam -lpam_misc -lcrypt | |
| 35 | +// | |
| 36 | +// To deploy, copy to user libraries folder | |
| 37 | +// sudo cp GSF.POSIX.so /usr/lib/ | |
| 30 | 38 | // |
| 31 | 39 | |
| 40 | +#include <stdlib.h> | |
| 32 | 41 | #include <security/pam_appl.h> |
| 33 | 42 | #include <security/pam_misc.h> |
| 34 | 43 | #include <sys/types.h> |
| @@ -39,26 +48,14 @@ · 4 unmodified lines | ||
| 39 | 48 | #include <grp.h> |
| 40 | 49 | #include <shadow.h> |
| 41 | 50 | #include <crypt.h> |
| 42 | − | |
| 43 | −// Structure used to return key spwd information | |
| 44 | −struct UserPasswordInformation | |
| 45 | −{ | |
| 46 | − // Do not include any pointer types in this structure | |
| 47 | − // to keep marshaling into .NET simple | |
| 48 | − long lastChangeDate; | |
| 49 | − long minDaysForChange; | |
| 50 | − long maxDaysForChange; | |
| 51 | − long warningDays; | |
| 52 | − long inactivityDays; | |
| 53 | − long accountExpirationDate; | |
| 54 | −}; | |
| 51 | +#include "GSF.POSIX.h" | |
| 55 | 52 | |
| 56 | 53 | // Define custom PAM conversation function for authentication |
| 57 | 54 | int AuthenticateConveration(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr) |
| 58 | 55 | { |
| 59 | 56 | const struct pam_message* message = *msg; |
| 60 | 57 | |
| 61 | − if (num_msg == 1 && message->msg != NULL && message->msg_style == PAM_PROMPT_ECHO_ON) | |
| 58 | + if (num_msg == 1 && message->msg != NULL && message->msg_style == PAM_PROMPT_ECHO_OFF) | |
| 62 | 59 | { |
| 63 | 60 | // Provide password for the PAM conversation response that was passed into appdata_ptr |
| 64 | 61 | struct pam_response* reply = (struct pam_response*)malloc(sizeof(struct pam_response)); |
| @@ -139,8 +136,8 @@ int AuthenticateUser(const char* userName, const char* password) · 74 unmodified lines | ||
| 139 | 136 | pam_handle_t* pamh; |
| 140 | 137 | int retval; |
| 141 | 138 | |
| 142 | − // Start PAM - just associate with something simple like the "whoami" command | |
| 143 | − retval = pam_start("whoami", userName, &pamc, &pamh); | |
| 139 | + // Start PAM - just associate with something simple like the "passwd" command | |
| 140 | + retval = pam_start("gsf", userName, &pamc, &pamh); | |
| 144 | 141 | |
| 145 | 142 | if (retval == PAM_SUCCESS) |
| 146 | 143 | { |
| @@ -0,0 +1,73 @@ | ||
| 1 | +//****************************************************************************************************** | |
| 2 | +// GSF.POSIX.h - Gbtc | |
| 3 | +// | |
| 4 | +// Copyright � 2014, Grid Protection Alliance. All Rights Reserved. | |
| 5 | +// | |
| 6 | +// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | |
| 7 | +// the NOTICE file distributed with this work for additional information regarding copyright ownership. | |
| 8 | +// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | |
| 9 | +// not use this file except in compliance with the License. You may obtain a copy of the License at: | |
| 10 | +// | |
| 11 | +// http://www.opensource.org/licenses/eclipse-1.0.php | |
| 12 | +// | |
| 13 | +// Unless agreed to in writing, the subject software distributed under the License is distributed on an | |
| 14 | +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | |
| 15 | +// License for the specific language governing permissions and limitations. | |
| 16 | +// | |
| 17 | +// Code Modification History: | |
| 18 | +// ---------------------------------------------------------------------------------------------------- | |
| 19 | +// 09/14/2014 - J. Ritchie Carroll | |
| 20 | +// Generated original version of source code. | |
| 21 | +// | |
| 22 | +//****************************************************************************************************** | |
| 23 | + | |
| 24 | +// Structure used to return key spwd information | |
| 25 | +struct UserPasswordInformation | |
| 26 | +{ | |
| 27 | + // Do not include any pointer types in this structure | |
| 28 | + // to keep marshaling into .NET simple | |
| 29 | + long lastChangeDate; | |
| 30 | + long minDaysForChange; | |
| 31 | + long maxDaysForChange; | |
| 32 | + long warningDays; | |
| 33 | + long inactivityDays; | |
| 34 | + long accountExpirationDate; | |
| 35 | +}; | |
| 36 | + | |
| 37 | +int AuthenticateUser(const char* userName, const char* password); | |
| 38 | + | |
| 39 | +int ChangeUserPassword(const char* userName, const char* oldPassword, const char* newPassword); | |
| 40 | + | |
| 41 | +int GetLocalUserID(const char* userName, /*out*/ unsigned int* uid); | |
| 42 | + | |
| 43 | +// Preallocate outbound userName to 256 characters | |
| 44 | +int GetLocalUserName(unsigned int uid, /*out*/ char* userName); | |
| 45 | + | |
| 46 | +char* GetLocalUserHomeDirectory(const char* userName); | |
| 47 | + | |
| 48 | +char* GetLocalUserGecos(const char* userName); | |
| 49 | + | |
| 50 | +// Values for status parameter: | |
| 51 | +// 1 -- "*" Account is disabled | |
| 52 | +// 2 -- "!<...>" The account locked out (e.g., with passwd -l <username>) | |
| 53 | +// 2 -- "!" The password expired / never set - effectively locked out | |
| 54 | +// 2 -- "!!" The password expired / never set - effectively locked out | |
| 55 | +// 3 -- "" No password defined | |
| 56 | +// 0 -- "<else>" Account assumed normal (encrypted password) | |
| 57 | +int GetLocalUserPasswordInformation(const char* userName, struct UserPasswordInformation* userPasswordInfo, /*out*/ int* status); | |
| 58 | + | |
| 59 | +int SetLocalUserPassword(const char* userName, const char* password, const char* salt); | |
| 60 | + | |
| 61 | +char* GetPasswordHash(const char* password, const char* salt); | |
| 62 | + | |
| 63 | +int GetLocalUserGroupCount(const char* userName); | |
| 64 | + | |
| 65 | +// Preallocate outbound groupIDs as an unsigned integer array sized from GetLocalUserGroupCount | |
| 66 | +int GetLocalUserGroupIDs(const char* userName, int groupCount, /*out*/ gid_t** groupIDs); | |
| 67 | + | |
| 68 | +int GetLocalGroupID(const char* groupName, /*out*/ unsigned int* gid); | |
| 69 | + | |
| 70 | +// Preallocate outbound groupName to 256 characters | |
| 71 | +int GetLocalGroupName(unsigned int gid, /*out*/ char* groupName); | |
| 72 | + | |
| 73 | +char** GetLocalGroupMembers(const char* groupName); | |
| @@ -11,9 +11,14 @@ · 10 unmodified lines | ||
| 11 | 11 | </ProjectConfiguration> |
| 12 | 12 | </ItemGroup> |
| 13 | 13 | <ItemGroup> |
| 14 | + <ClCompile Include="gsf.c" /> | |
| 14 | 15 | <ClCompile Include="GSF.POSIX.c"> |
| 15 | 16 | <DeploymentContent>false</DeploymentContent> |
| 16 | 17 | </ClCompile> |
| 18 | + <ClCompile Include="test.c" /> | |
| 19 | + </ItemGroup> | |
| 20 | + <ItemGroup> | |
| 21 | + <ClInclude Include="GSF.POSIX.h" /> | |
| 17 | 22 | </ItemGroup> |
| 18 | 23 | <PropertyGroup Label="Globals"> |
| 19 | 24 | <ProjectGuid>{63AF9800-2CDE-41F7-9706-76EF0AE181CE}</ProjectGuid> |
| @@ -18,5 +18,16 @@ · 17 unmodified lines | ||
| 18 | 18 | <ClCompile Include="GSF.POSIX.c"> |
| 19 | 19 | <Filter>Source Files</Filter> |
| 20 | 20 | </ClCompile> |
| 21 | + <ClCompile Include="gsf.c"> | |
| 22 | + <Filter>Source Files</Filter> | |
| 23 | + </ClCompile> | |
| 24 | + <ClCompile Include="test.c"> | |
| 25 | + <Filter>Source Files</Filter> | |
| 26 | + </ClCompile> | |
| 27 | + </ItemGroup> | |
| 28 | + <ItemGroup> | |
| 29 | + <ClInclude Include="GSF.POSIX.h"> | |
| 30 | + <Filter>Header Files</Filter> | |
| 31 | + </ClInclude> | |
| 21 | 32 | </ItemGroup> |
| 22 | 33 | </Project> |
| @@ -0,0 +1,84 @@ | ||
| 1 | +//****************************************************************************************************** | |
| 2 | +// gsf.c - Gbtc | |
| 3 | +// | |
| 4 | +// Copyright � 2014, Grid Protection Alliance. All Rights Reserved. | |
| 5 | +// | |
| 6 | +// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | |
| 7 | +// the NOTICE file distributed with this work for additional information regarding copyright ownership. | |
| 8 | +// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | |
| 9 | +// not use this file except in compliance with the License. You may obtain a copy of the License at: | |
| 10 | +// | |
| 11 | +// http://www.opensource.org/licenses/eclipse-1.0.php | |
| 12 | +// | |
| 13 | +// Unless agreed to in writing, the subject software distributed under the License is distributed on an | |
| 14 | +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | |
| 15 | +// License for the specific language governing permissions and limitations. | |
| 16 | +// | |
| 17 | +// Code Modification History: | |
| 18 | +// ---------------------------------------------------------------------------------------------------- | |
| 19 | +// 08/29/2014 - J. Ritchie Carroll | |
| 20 | +// Generated original version of source code. | |
| 21 | +// | |
| 22 | +//****************************************************************************************************** | |
| 23 | + | |
| 24 | +// This will create a hosted Mono service that contains needed GSF functions | |
| 25 | + | |
| 26 | +// Compiling for Linux: | |
| 27 | +// | |
| 28 | +// Get PAM development libraries, e.g., for Ubuntu: apt-get install libpam0g-dev | |
| 29 | +// | |
| 30 | +// Compile GSF.POSIX.o object library first, then... | |
| 31 | +// | |
| 32 | +// To compile as a mono hosted executable: | |
| 33 | +// gcc -o gsf gsf.c `pkg-config --cflags --libs mono-2` GSF.POSIX.o -lm -lpam -lpam_misc -lcrypt -rdynamic | |
| 34 | +// | |
| 35 | +// To export symbols for DllImport("__Internal") use gcc parameter -rdynamic | |
| 36 | +// | |
| 37 | + | |
| 38 | +#include <mono/jit/jit.h> | |
| 39 | +#include <mono/metadata/environment.h> | |
| 40 | +#include <stdlib.h> | |
| 41 | + | |
| 42 | +int main(int argc, char* argv[]) | |
| 43 | +{ | |
| 44 | + MonoDomain *domain; | |
| 45 | + MonoAssembly *assembly; | |
| 46 | + const char *file; | |
| 47 | + int retval; | |
| 48 | + | |
| 49 | + if (argc < 2) | |
| 50 | + { | |
| 51 | + fprintf(stderr, "Please provide name of .NET assembly to load.\n"); | |
| 52 | + return 1; | |
| 53 | + } | |
| 54 | + | |
| 55 | + file = argv[1]; | |
| 56 | + | |
| 57 | + // Load the default Mono configuration file, this is needed | |
| 58 | + // if you are planning on using the dllmaps defined on the | |
| 59 | + // system configuration | |
| 60 | + mono_config_parse(NULL); | |
| 61 | + | |
| 62 | + // Create mono AppDomain | |
| 63 | + domain = mono_jit_init(file); | |
| 64 | + | |
| 65 | + // Open entry assembly in new AppDomain | |
| 66 | + assembly = mono_domain_assembly_open(domain, file); | |
| 67 | + | |
| 68 | + if (assembly != NULL) | |
| 69 | + { | |
| 70 | + // mono_jit_exec runs the Main() method in the assembly | |
| 71 | + mono_jit_exec(domain, assembly, argc - 1, argv + 1); | |
| 72 | + | |
| 73 | + // Get exit code from entry assembly | |
| 74 | + retval = mono_environment_exitcode_get(); | |
| 75 | + } | |
| 76 | + else | |
| 77 | + { | |
| 78 | + retval = 2; | |
| 79 | + } | |
| 80 | + | |
| 81 | + mono_jit_cleanup(domain); | |
| 82 | + | |
| 83 | + return retval; | |
| 84 | +} | |
| @@ -0,0 +1,63 @@ | ||
| 1 | +//****************************************************************************************************** | |
| 2 | +// test.c - Gbtc | |
| 3 | +// | |
| 4 | +// Copyright � 2014, Grid Protection Alliance. All Rights Reserved. | |
| 5 | +// | |
| 6 | +// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | |
| 7 | +// the NOTICE file distributed with this work for additional information regarding copyright ownership. | |
| 8 | +// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | |
| 9 | +// not use this file except in compliance with the License. You may obtain a copy of the License at: | |
| 10 | +// | |
| 11 | +// http://www.opensource.org/licenses/eclipse-1.0.php | |
| 12 | +// | |
| 13 | +// Unless agreed to in writing, the subject software distributed under the License is distributed on an | |
| 14 | +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | |
| 15 | +// License for the specific language governing permissions and limitations. | |
| 16 | +// | |
| 17 | +// Code Modification History: | |
| 18 | +// ---------------------------------------------------------------------------------------------------- | |
| 19 | +// 08/29/2014 - J. Ritchie Carroll | |
| 20 | +// Generated original version of source code. | |
| 21 | +// | |
| 22 | +//****************************************************************************************************** | |
| 23 | + | |
| 24 | +// Compiling for Linux: | |
| 25 | +// | |
| 26 | +// Compile GSF.POSIX.o object library first, then... | |
| 27 | +// | |
| 28 | +// To compile as a mono hosted executable: | |
| 29 | +// gcc -o test test.c GSF.POSIX.o -lpam -lpam_misc -lcrypt | |
| 30 | +// | |
| 31 | + | |
| 32 | +#include <stdlib.h> | |
| 33 | +#include <stdio.h> | |
| 34 | +#include "GSF.POSIX.h" | |
| 35 | + | |
| 36 | +int main(int argc, char* argv[]) | |
| 37 | +{ | |
| 38 | + int retval; | |
| 39 | + | |
| 40 | + if (argc != 2) | |
| 41 | + { | |
| 42 | + fprintf(stderr, "Specify user name as an argument.\n"); | |
| 43 | + retval = 1; | |
| 44 | + } | |
| 45 | + else | |
| 46 | + { | |
| 47 | + struct UserPasswordInformation info; | |
| 48 | + int status; | |
| 49 | + int retval = GetLocalUserPasswordInformation(argv[1], &info, &status); | |
| 50 | + | |
| 51 | + fprintf(stdout, "retval = %d\n", retval); | |
| 52 | + | |
| 53 | + if (retval == 0) | |
| 54 | + { | |
| 55 | + fprintf(stdout, "lastChangeDate = %ld\n", info.lastChangeDate); | |
| 56 | + fprintf(stdout, "minDaysForChange = %ld\n", info.minDaysForChange); | |
| 57 | + fprintf(stdout, "maxDaysForChange = %ld\n", info.maxDaysForChange); | |
| 58 | + fprintf(stdout, "status = %d\n", status); | |
| 59 | + } | |
| 60 | + } | |
| 61 | + | |
| 62 | + return retval; | |
| 63 | +} | |
| @@ -1,9 +1,5 @@ | ||
| 1 | 1 | using System; |
| 2 | −using System.Collections.Generic; | |
| 3 | −using System.Linq; | |
| 4 | 2 | using System.Security.Principal; |
| 5 | −using System.Text; | |
| 6 | −using System.Threading.Tasks; | |
| 7 | 3 | using GSF.Collections; |
| 8 | 4 | using GSF.Identity; |
| 9 | 5 | |
| @@ -40,10 +36,10 @@ namespace UserInfoTest · 30 unmodified lines | ||
| 40 | 36 | Console.WriteLine("Current user: " + info.LoginID); |
| 41 | 37 | |
| 42 | 38 | Console.WriteLine("Attempting initialization..."); |
| 43 | − | |
| 39 | + | |
| 44 | 40 | info.Initialize(); |
| 45 | 41 | |
| 46 | − Console.WriteLine("Groups: " + info.LocalGroups.ToDelimitedString()); | |
| 42 | + Console.WriteLine("Groups: " + info.Groups.ToDelimitedString()); | |
| 47 | 43 | |
| 48 | 44 | Console.WriteLine("Next password change date: " + info.NextPasswordChangeDate); |
| 49 | 45 | |