History

Updates to Unix based UserInfo implementation.

ritchiecarroll committed 12 years ago

Commit bf22ae21 parent 2ab4c339 files · +284 −43Browse files

Unified · Split

9 files
  1. Source/Libraries/GSF.Core/Console/Command.cs +5 −5
  2. Source/Libraries/GSF.Core/Identity/UnixUserInfo.cs +26 −14
  3. Source/Tools/UnixTools/GSF.POSIX.c +15 −18
  4. Source/Tools/UnixTools/GSF.POSIX.h +73 −0
  5. Source/Tools/UnixTools/UnixTools.vcxproj +5 −0
  6. Source/Tools/UnixTools/UnixTools.vcxproj.filters +11 −0
  7. Source/Tools/UnixTools/gsf.c +84 −0
  8. Source/Tools/UnixTools/test.c +63 −0
  9. Source/Tools/UserInfoTest/Program.cs +2 −6
Source/Libraries/GSF.Core/Console/Command.cs+5−5
@@ -74,9 +74,6 @@ namespace GSF.Console · 73 unmodified lines
74 74
75 m_process.OutputDataReceived += m_process_OutputDataReceived;75 m_process.OutputDataReceived += m_process_OutputDataReceived;
76 m_process.ErrorDataReceived += m_process_ErrorDataReceived;76 m_process.ErrorDataReceived += m_process_ErrorDataReceived;
77
78 m_process.BeginOutputReadLine();
79 m_process.BeginErrorReadLine();
80 }77 }
81 78
82 /// <summary>79 /// <summary>
@@ -170,6 +167,9 @@ namespace GSF.Console · 87 unmodified lines
170 {167 {
171 m_process.Start();168 m_process.Start();
172 169
170 m_process.BeginOutputReadLine();
171 m_process.BeginErrorReadLine();
172
173 if (!m_process.WaitForExit(timeout))173 if (!m_process.WaitForExit(timeout))
174 {174 {
175 m_process.CancelOutputRead();175 m_process.CancelOutputRead();
@@ -183,12 +183,12 @@ namespace GSF.Console · 7 unmodified lines
183 183
184 private void m_process_OutputDataReceived(object sender, DataReceivedEventArgs e)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 private void m_process_ErrorDataReceived(object sender, DataReceivedEventArgs e)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 #endregion194 #endregion
Source/Libraries/GSF.Core/Identity/UnixUserInfo.cs+26−14
@@ -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
24using System;27using System;
25using System.Collections;28using System.Collections;
26using System.Collections.Generic;29using System.Collections.Generic;
@@ -44,6 +47,12 @@ namespace GSF.Identity · 17 unmodified lines
44 // Unix implementation of key UserInfo class elements47 // Unix implementation of key UserInfo class elements
45 internal class UnixUserInfo : IUserInfo48 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 #region [ Members ]56 #region [ Members ]
48 57
49 // Nested Types58 // Nested Types
@@ -450,7 +459,7 @@ namespace GSF.Identity · 400 unmodified lines
450 if (!m_isLocalAccount)459 if (!m_isLocalAccount)
451 return GetUserPropertyValueCollection("memberOf");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 if (string.IsNullOrWhiteSpace(userName))491 if (string.IsNullOrWhiteSpace(userName))
483 return m_parent.UserName;492 return m_parent.UserName;
484 493
494 if (userName.Contains(","))
495 userName = userName.Split(',')[0];
496
485 return userName;497 return userName;
486 }498 }
487 }499 }
@@ -1271,51 +1283,51 @@ namespace GSF.Identity · 783 unmodified lines
1271 #endregion1283 #endregion
1272 1284
1273 // AuthenticateUser function is PAM based, so it will support more than local users1285 // AuthenticateUser function is PAM based, so it will support more than local users
1274 [DllImport("GSF.POSIX.so")]1286 [DllImport(IMPORT)]
1275 private static extern int AuthenticateUser(string userName, string password);1287 private static extern int AuthenticateUser(string userName, string password);
1276 1288
1277 // ChangeUserPassword function is PAM based, so it will support more than local users1289 // ChangeUserPassword function is PAM based, so it will support more than local users
1278 [DllImport("GSF.POSIX.so")]1290 [DllImport(IMPORT)]
1279 private static extern int ChangeUserPassword(string userName, string oldPassword, string newPassword);1291 private static extern int ChangeUserPassword(string userName, string oldPassword, string newPassword);
1280 1292
1281 [DllImport("GSF.POSIX.so")]1293 [DllImport(IMPORT)]
1282 private static extern int GetLocalUserID(string userName, out uint userID);1294 private static extern int GetLocalUserID(string userName, out uint userID);
1283 1295
1284 // Preallocate outbound userName to 256 characters1296 // Preallocate outbound userName to 256 characters
1285 [DllImport("GSF.POSIX.so")]1297 [DllImport(IMPORT)]
1286 private static extern int GetLocalUserName(uint uid, StringBuilder userName);1298 private static extern int GetLocalUserName(uint uid, StringBuilder userName);
1287 1299
1288 // Returns a char* that needs to marshaled to a .NET string1300 // Returns a char* that needs to marshaled to a .NET string
1289 [DllImport("GSF.POSIX.so")]1301 [DllImport(IMPORT)]
1290 private static extern IntPtr GetLocalUserGecos(string userName);1302 private static extern IntPtr GetLocalUserGecos(string userName);
1291 1303
1292 // UserPasswordInformation structure contains only blittable types so it will be marshaled by reference 1304 // UserPasswordInformation structure contains only blittable types so it will be marshaled by reference
1293 [DllImport("GSF.POSIX.so")]1305 [DllImport(IMPORT)]
1294 private static extern int GetLocalUserPasswordInformation(string userName, UserPasswordInformation userPasswordInfo, out AccountStatus status);1306 private static extern int GetLocalUserPasswordInformation(string userName, UserPasswordInformation userPasswordInfo, out AccountStatus status);
1295 1307
1296 [DllImport("GSF.POSIX.so")]1308 [DllImport(IMPORT)]
1297 private static extern int SetLocalUserPassword(string userName, string password, string salt);1309 private static extern int SetLocalUserPassword(string userName, string password, string salt);
1298 1310
1299 // Returns a char* that needs to be marshaled to a .NET string1311 // Returns a char* that needs to be marshaled to a .NET string
1300 [DllImport("GSF.POSIX.so")]1312 [DllImport(IMPORT)]
1301 private static extern IntPtr GetPasswordHash(string password, string salt);1313 private static extern IntPtr GetPasswordHash(string password, string salt);
1302 1314
1303 [DllImport("GSF.POSIX.so")]1315 [DllImport(IMPORT)]
1304 private static extern int GetLocalUserGroupCount(string userName);1316 private static extern int GetLocalUserGroupCount(string userName);
1305 1317
1306 // Preallocate groupIDs as an unsigned integer array sized from GetLocalUserGroupCount1318 // Preallocate groupIDs as an unsigned integer array sized from GetLocalUserGroupCount
1307 [DllImport("GSF.POSIX.so")]1319 [DllImport(IMPORT)]
1308 private static extern int GetLocalUserGroupIDs(string userName, int groupCount, ref uint[] groupsIDs);1320 private static extern int GetLocalUserGroupIDs(string userName, int groupCount, ref uint[] groupsIDs);
1309 1321
1310 [DllImport("GSF.POSIX.so")]1322 [DllImport(IMPORT)]
1311 private static extern int GetLocalGroupID(string groupName, out uint groupID);1323 private static extern int GetLocalGroupID(string groupName, out uint groupID);
1312 1324
1313 // Preallocate outbound userName to 256 characters1325 // Preallocate outbound userName to 256 characters
1314 [DllImport("GSF.POSIX.so")]1326 [DllImport(IMPORT)]
1315 private static extern int GetLocalGroupName(uint uid, StringBuilder groupName);1327 private static extern int GetLocalGroupName(uint uid, StringBuilder groupName);
1316 1328
1317 // Returns a char** that needs to be marshaled to a .NET string array1329 // Returns a char** that needs to be marshaled to a .NET string array
1318 [DllImport("GSF.POSIX.so")]1330 [DllImport(IMPORT)]
1319 private static extern IntPtr GetLocalGroupMembers(string groupName);1331 private static extern IntPtr GetLocalGroupMembers(string groupName);
1320 1332
1321 #endregion1333 #endregion
Source/Tools/UnixTools/GSF.POSIX.c+15−18
@@ -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// Compiling for Linux:26// Compiling for Linux:
25//27//
26// Get PAM development libraries, e.g., for Ubuntu: apt-get install libpam0g-dev28// Get PAM development libraries, e.g., for Ubuntu: apt-get install libpam0g-dev
27//29//
30// To compile to an object library
28// gcc -c -Wall -Werror -fpic GSF.POSIX.c31// gcc -c -Wall -Werror -fpic GSF.POSIX.c
29// gcc -shared -o GSF.POSIX.so GSF.POSIX.o -lpam -lpam_misc32//
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#include <security/pam_appl.h>41#include <security/pam_appl.h>
33#include <security/pam_misc.h>42#include <security/pam_misc.h>
34#include <sys/types.h>43#include <sys/types.h>
@@ -39,26 +48,14 @@ · 4 unmodified lines
39#include <grp.h>48#include <grp.h>
40#include <shadow.h>49#include <shadow.h>
41#include <crypt.h>50#include <crypt.h>
42 51#include "GSF.POSIX.h"
43// Structure used to return key spwd information
44struct 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};
55 52
56// Define custom PAM conversation function for authentication53// Define custom PAM conversation function for authentication
57int AuthenticateConveration(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr)54int AuthenticateConveration(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr)
58{55{
59 const struct pam_message* message = *msg;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 // Provide password for the PAM conversation response that was passed into appdata_ptr60 // Provide password for the PAM conversation response that was passed into appdata_ptr
64 struct pam_response* reply = (struct pam_response*)malloc(sizeof(struct pam_response));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 pam_handle_t* pamh; 136 pam_handle_t* pamh;
140 int retval;137 int retval;
141 138
142 // Start PAM - just associate with something simple like the "whoami" command139 // Start PAM - just associate with something simple like the "passwd" command
143 retval = pam_start("whoami", userName, &pamc, &pamh);140 retval = pam_start("gsf", userName, &pamc, &pamh);
144 141
145 if (retval == PAM_SUCCESS)142 if (retval == PAM_SUCCESS)
146 {143 {
Source/Tools/UnixTools/GSF.POSIX.h+73−0
@@ -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
25struct 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
37int AuthenticateUser(const char* userName, const char* password);
38
39int ChangeUserPassword(const char* userName, const char* oldPassword, const char* newPassword);
40
41int GetLocalUserID(const char* userName, /*out*/ unsigned int* uid);
42
43// Preallocate outbound userName to 256 characters
44int GetLocalUserName(unsigned int uid, /*out*/ char* userName);
45
46char* GetLocalUserHomeDirectory(const char* userName);
47
48char* 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)
57int GetLocalUserPasswordInformation(const char* userName, struct UserPasswordInformation* userPasswordInfo, /*out*/ int* status);
58
59int SetLocalUserPassword(const char* userName, const char* password, const char* salt);
60
61char* GetPasswordHash(const char* password, const char* salt);
62
63int GetLocalUserGroupCount(const char* userName);
64
65// Preallocate outbound groupIDs as an unsigned integer array sized from GetLocalUserGroupCount
66int GetLocalUserGroupIDs(const char* userName, int groupCount, /*out*/ gid_t** groupIDs);
67
68int GetLocalGroupID(const char* groupName, /*out*/ unsigned int* gid);
69
70// Preallocate outbound groupName to 256 characters
71int GetLocalGroupName(unsigned int gid, /*out*/ char* groupName);
72
73char** GetLocalGroupMembers(const char* groupName);
Source/Tools/UnixTools/UnixTools.vcxproj+5−0
@@ -11,9 +11,14 @@ · 10 unmodified lines
11 </ProjectConfiguration>11 </ProjectConfiguration>
12 </ItemGroup>12 </ItemGroup>
13 <ItemGroup>13 <ItemGroup>
14 <ClCompile Include="gsf.c" />
14 <ClCompile Include="GSF.POSIX.c">15 <ClCompile Include="GSF.POSIX.c">
15 <DeploymentContent>false</DeploymentContent>16 <DeploymentContent>false</DeploymentContent>
16 </ClCompile>17 </ClCompile>
18 <ClCompile Include="test.c" />
19 </ItemGroup>
20 <ItemGroup>
21 <ClInclude Include="GSF.POSIX.h" />
17 </ItemGroup>22 </ItemGroup>
18 <PropertyGroup Label="Globals">23 <PropertyGroup Label="Globals">
19 <ProjectGuid>{63AF9800-2CDE-41F7-9706-76EF0AE181CE}</ProjectGuid>24 <ProjectGuid>{63AF9800-2CDE-41F7-9706-76EF0AE181CE}</ProjectGuid>
Source/Tools/UnixTools/UnixTools.vcxproj.filters+11−0
@@ -18,5 +18,16 @@ · 17 unmodified lines
18 <ClCompile Include="GSF.POSIX.c">18 <ClCompile Include="GSF.POSIX.c">
19 <Filter>Source Files</Filter>19 <Filter>Source Files</Filter>
20 </ClCompile>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 </ItemGroup>32 </ItemGroup>
22</Project>33</Project>
Source/Tools/UnixTools/gsf.c+84−0
@@ -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
42int 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}
Source/Tools/UnixTools/test.c+63−0
@@ -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
36int 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}
Source/Tools/UserInfoTest/Program.cs+2−6
@@ -1,9 +1,5 @@
1using System;1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Security.Principal;2using System.Security.Principal;
5using System.Text;
6using System.Threading.Tasks;
7using GSF.Collections;3using GSF.Collections;
8using GSF.Identity;4using GSF.Identity;
9 5
@@ -40,10 +36,10 @@ namespace UserInfoTest · 30 unmodified lines
40 Console.WriteLine("Current user: " + info.LoginID);36 Console.WriteLine("Current user: " + info.LoginID);
41 37
42 Console.WriteLine("Attempting initialization...");38 Console.WriteLine("Attempting initialization...");
43 39
44 info.Initialize();40 info.Initialize();
45 41
46 Console.WriteLine("Groups: " + info.LocalGroups.ToDelimitedString());42 Console.WriteLine("Groups: " + info.Groups.ToDelimitedString());
47 43
48 Console.WriteLine("Next password change date: " + info.NextPasswordChangeDate);44 Console.WriteLine("Next password change date: " + info.NextPasswordChangeDate);
49 45

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t