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
7474
7575 m_process.OutputDataReceived += m_process_OutputDataReceived;
7676 m_process.ErrorDataReceived += m_process_ErrorDataReceived;
77−
78− m_process.BeginOutputReadLine();
79− m_process.BeginErrorReadLine();
8077 }
8178
8279 /// <summary>
@@ -170,6 +167,9 @@ namespace GSF.Console · 87 unmodified lines
170167 {
171168 m_process.Start();
172169
170+ m_process.BeginOutputReadLine();
171+ m_process.BeginErrorReadLine();
172+
173173 if (!m_process.WaitForExit(timeout))
174174 {
175175 m_process.CancelOutputRead();
@@ -183,12 +183,12 @@ namespace GSF.Console · 7 unmodified lines
183183
184184 private void m_process_OutputDataReceived(object sender, DataReceivedEventArgs e)
185185 {
186− m_standardOutput.Append(e.Data);
186+ m_standardOutput.AppendLine(e.Data);
187187 }
188188
189189 private void m_process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
190190 {
191− m_standardError.Append(e.Data);
191+ m_standardError.AppendLine(e.Data);
192192 }
193193
194194 #endregion
Source/Libraries/GSF.Core/Identity/UnixUserInfo.cs+26−14
@@ -21,6 +21,9 @@ · 20 unmodified lines
2121 //
2222 //******************************************************************************************************
2323
24+// Undefine to use internally linked unmanaged functions (e.g., when Mono hosted in gsf service)
25+#define USE_SHARED_OBJECT
26+
2427 using System;
2528 using System.Collections;
2629 using System.Collections.Generic;
@@ -44,6 +47,12 @@ namespace GSF.Identity · 17 unmodified lines
4447 // Unix implementation of key UserInfo class elements
4548 internal class UnixUserInfo : IUserInfo
4649 {
50+#if USE_SHARED_OBJECT
51+ private const string IMPORT = "GSF.POSIX.so";
52+#else
53+ private const string IMPORT = "__Internal";
54+#endif
55+
4756 #region [ Members ]
4857
4958 // Nested Types
@@ -450,7 +459,7 @@ namespace GSF.Identity · 400 unmodified lines
450459 if (!m_isLocalAccount)
451460 return GetUserPropertyValueCollection("memberOf");
452461
453− return new string[0];
462+ return LocalGroups;
454463 }
455464 }
456465
@@ -482,6 +491,9 @@ namespace GSF.Identity · 25 unmodified lines
482491 if (string.IsNullOrWhiteSpace(userName))
483492 return m_parent.UserName;
484493
494+ if (userName.Contains(","))
495+ userName = userName.Split(',')[0];
496+
485497 return userName;
486498 }
487499 }
@@ -1271,51 +1283,51 @@ namespace GSF.Identity · 783 unmodified lines
12711283 #endregion
12721284
12731285 // AuthenticateUser function is PAM based, so it will support more than local users
1274− [DllImport("GSF.POSIX.so")]
1286+ [DllImport(IMPORT)]
12751287 private static extern int AuthenticateUser(string userName, string password);
12761288
12771289 // ChangeUserPassword function is PAM based, so it will support more than local users
1278− [DllImport("GSF.POSIX.so")]
1290+ [DllImport(IMPORT)]
12791291 private static extern int ChangeUserPassword(string userName, string oldPassword, string newPassword);
12801292
1281− [DllImport("GSF.POSIX.so")]
1293+ [DllImport(IMPORT)]
12821294 private static extern int GetLocalUserID(string userName, out uint userID);
12831295
12841296 // Preallocate outbound userName to 256 characters
1285− [DllImport("GSF.POSIX.so")]
1297+ [DllImport(IMPORT)]
12861298 private static extern int GetLocalUserName(uint uid, StringBuilder userName);
12871299
12881300 // Returns a char* that needs to marshaled to a .NET string
1289− [DllImport("GSF.POSIX.so")]
1301+ [DllImport(IMPORT)]
12901302 private static extern IntPtr GetLocalUserGecos(string userName);
12911303
12921304 // UserPasswordInformation structure contains only blittable types so it will be marshaled by reference
1293− [DllImport("GSF.POSIX.so")]
1305+ [DllImport(IMPORT)]
12941306 private static extern int GetLocalUserPasswordInformation(string userName, UserPasswordInformation userPasswordInfo, out AccountStatus status);
12951307
1296− [DllImport("GSF.POSIX.so")]
1308+ [DllImport(IMPORT)]
12971309 private static extern int SetLocalUserPassword(string userName, string password, string salt);
12981310
12991311 // Returns a char* that needs to be marshaled to a .NET string
1300− [DllImport("GSF.POSIX.so")]
1312+ [DllImport(IMPORT)]
13011313 private static extern IntPtr GetPasswordHash(string password, string salt);
13021314
1303− [DllImport("GSF.POSIX.so")]
1315+ [DllImport(IMPORT)]
13041316 private static extern int GetLocalUserGroupCount(string userName);
13051317
13061318 // Preallocate groupIDs as an unsigned integer array sized from GetLocalUserGroupCount
1307− [DllImport("GSF.POSIX.so")]
1319+ [DllImport(IMPORT)]
13081320 private static extern int GetLocalUserGroupIDs(string userName, int groupCount, ref uint[] groupsIDs);
13091321
1310− [DllImport("GSF.POSIX.so")]
1322+ [DllImport(IMPORT)]
13111323 private static extern int GetLocalGroupID(string groupName, out uint groupID);
13121324
13131325 // Preallocate outbound userName to 256 characters
1314− [DllImport("GSF.POSIX.so")]
1326+ [DllImport(IMPORT)]
13151327 private static extern int GetLocalGroupName(uint uid, StringBuilder groupName);
13161328
13171329 // Returns a char** that needs to be marshaled to a .NET string array
1318− [DllImport("GSF.POSIX.so")]
1330+ [DllImport(IMPORT)]
13191331 private static extern IntPtr GetLocalGroupMembers(string groupName);
13201332
13211333 #endregion
Source/Tools/UnixTools/GSF.POSIX.c+15−18
@@ -21,14 +21,23 @@ · 20 unmodified lines
2121 //
2222 //******************************************************************************************************
2323
24+// This will create a shared object for needed GSF functions
25+
2426 // Compiling for Linux:
2527 //
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
2729 //
30+// To compile to an object library
2831 // 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/
3038 //
3139
40+#include <stdlib.h>
3241 #include <security/pam_appl.h>
3342 #include <security/pam_misc.h>
3443 #include <sys/types.h>
@@ -39,26 +48,14 @@ · 4 unmodified lines
3948 #include <grp.h>
4049 #include <shadow.h>
4150 #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"
5552
5653 // Define custom PAM conversation function for authentication
5754 int AuthenticateConveration(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr)
5855 {
5956 const struct pam_message* message = *msg;
6057
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)
6259 {
6360 // Provide password for the PAM conversation response that was passed into appdata_ptr
6461 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
139136 pam_handle_t* pamh;
140137 int retval;
141138
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);
144141
145142 if (retval == PAM_SUCCESS)
146143 {
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
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);
Source/Tools/UnixTools/UnixTools.vcxproj+5−0
@@ -11,9 +11,14 @@ · 10 unmodified lines
1111 </ProjectConfiguration>
1212 </ItemGroup>
1313 <ItemGroup>
14+ <ClCompile Include="gsf.c" />
1415 <ClCompile Include="GSF.POSIX.c">
1516 <DeploymentContent>false</DeploymentContent>
1617 </ClCompile>
18+ <ClCompile Include="test.c" />
19+ </ItemGroup>
20+ <ItemGroup>
21+ <ClInclude Include="GSF.POSIX.h" />
1722 </ItemGroup>
1823 <PropertyGroup Label="Globals">
1924 <ProjectGuid>{63AF9800-2CDE-41F7-9706-76EF0AE181CE}</ProjectGuid>
Source/Tools/UnixTools/UnixTools.vcxproj.filters+11−0
@@ -18,5 +18,16 @@ · 17 unmodified lines
1818 <ClCompile Include="GSF.POSIX.c">
1919 <Filter>Source Files</Filter>
2020 </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>
2132 </ItemGroup>
2233 </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+
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+}
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+
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+}
Source/Tools/UserInfoTest/Program.cs+2−6
@@ -1,9 +1,5 @@
11 using System;
2−using System.Collections.Generic;
3−using System.Linq;
42 using System.Security.Principal;
5−using System.Text;
6−using System.Threading.Tasks;
73 using GSF.Collections;
84 using GSF.Identity;
95
@@ -40,10 +36,10 @@ namespace UserInfoTest · 30 unmodified lines
4036 Console.WriteLine("Current user: " + info.LoginID);
4137
4238 Console.WriteLine("Attempting initialization...");
43−
39+
4440 info.Initialize();
4541
46− Console.WriteLine("Groups: " + info.LocalGroups.ToDelimitedString());
42+ Console.WriteLine("Groups: " + info.Groups.ToDelimitedString());
4743
4844 Console.WriteLine("Next password change date: " + info.NextPasswordChangeDate);
4945

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