1 //
2 // Mono.Unix/UnixUserInfo.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004-2005 Jonathan Pryor
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 
29 using System;
30 using System.Collections;
31 using System.Text;
32 using Mono.Unix;
33 
34 namespace Mono.Unix {
35 
36 	public sealed class UnixUserInfo
37 	{
38 		private Native.Passwd passwd;
39 
UnixUserInfo(string user)40 		public UnixUserInfo (string user)
41 		{
42 			passwd = new Native.Passwd ();
43 			Native.Passwd pw;
44 			int r = Native.Syscall.getpwnam_r (user, passwd, out pw);
45 			if (r != 0 || pw == null)
46 				throw new ArgumentException (Locale.GetText ("invalid username"), "user");
47 		}
48 
49 		[CLSCompliant (false)]
UnixUserInfo(uint user)50 		public UnixUserInfo (uint user)
51 		{
52 			passwd = new Native.Passwd ();
53 			Native.Passwd pw;
54 			int r = Native.Syscall.getpwuid_r (user, passwd, out pw);
55 			if (r != 0 || pw == null)
56 				throw new ArgumentException (Locale.GetText ("invalid user id"), "user");
57 		}
58 
UnixUserInfo(long user)59 		public UnixUserInfo (long user)
60 		{
61 			passwd = new Native.Passwd ();
62 			Native.Passwd pw;
63 			int r = Native.Syscall.getpwuid_r (Convert.ToUInt32 (user), passwd, out pw);
64 			if (r != 0 || pw == null)
65 				throw new ArgumentException (Locale.GetText ("invalid user id"), "user");
66 		}
67 
UnixUserInfo(Native.Passwd passwd)68 		public UnixUserInfo (Native.Passwd passwd)
69 		{
70 			this.passwd = CopyPasswd (passwd);
71 		}
72 
CopyPasswd(Native.Passwd pw)73 		private static Native.Passwd CopyPasswd (Native.Passwd pw)
74 		{
75 			Native.Passwd p = new Native.Passwd ();
76 
77 			p.pw_name   = pw.pw_name;
78 			p.pw_passwd = pw.pw_passwd;
79 			p.pw_uid    = pw.pw_uid;
80 			p.pw_gid    = pw.pw_gid;
81 			p.pw_gecos  = pw.pw_gecos;
82 			p.pw_dir    = pw.pw_dir;
83 			p.pw_shell  = pw.pw_shell;
84 
85 			return p;
86 		}
87 
88 		public string UserName {
89 			get {return passwd.pw_name;}
90 		}
91 
92 		public string Password {
93 			get {return passwd.pw_passwd;}
94 		}
95 
96 		public long UserId {
97 			get {return passwd.pw_uid;}
98 		}
99 
100 		public UnixGroupInfo Group {
101 			get {return new UnixGroupInfo (passwd.pw_gid);}
102 		}
103 
104 		public long GroupId {
105 			get {return passwd.pw_gid;}
106 		}
107 
108 		public string GroupName {
109 			get {return Group.GroupName;}
110 		}
111 
112 		public string RealName {
113 			get {return passwd.pw_gecos;}
114 		}
115 
116 		public string HomeDirectory {
117 			get {return passwd.pw_dir;}
118 		}
119 
120 		public string ShellProgram {
121 			get {return passwd.pw_shell;}
122 		}
123 
GetHashCode()124 		public override int GetHashCode ()
125 		{
126 			return passwd.GetHashCode ();
127 		}
128 
Equals(object obj)129 		public override bool Equals (object obj)
130 		{
131 			if (obj == null || GetType () != obj.GetType())
132 				return false;
133 			return passwd.Equals (((UnixUserInfo) obj).passwd);
134 		}
135 
ToString()136 		public override string ToString ()
137 		{
138 			return passwd.ToString ();
139 		}
140 
GetRealUser()141 		public static UnixUserInfo GetRealUser ()
142 		{
143 			return new UnixUserInfo (GetRealUserId ());
144 		}
145 
GetRealUserId()146 		public static long GetRealUserId ()
147 		{
148 			return Native.Syscall.getuid ();
149 		}
150 
151 		// I would hope that this is the same as GetCurrentUserName, but it is a
152 		// different syscall, so who knows.
GetLoginName()153 		public static string GetLoginName ()
154 		{
155 			StringBuilder buf = new StringBuilder (4);
156 			int r;
157 			do {
158 				buf.Capacity *= 2;
159 				r = Native.Syscall.getlogin_r (buf, (ulong) buf.Capacity);
160 			} while (r == (-1) && Native.Stdlib.GetLastError() == Native.Errno.ERANGE);
161 			UnixMarshal.ThrowExceptionForLastErrorIf (r);
162 			return buf.ToString ();
163 		}
164 
ToPasswd()165 		public Native.Passwd ToPasswd ()
166 		{
167 			return CopyPasswd (passwd);
168 		}
169 
GetLocalUsers()170 		public static UnixUserInfo[] GetLocalUsers ()
171 		{
172 			ArrayList entries = new ArrayList ();
173 			lock (Native.Syscall.pwd_lock) {
174 				if (Native.Syscall.setpwent () != 0) {
175 					UnixMarshal.ThrowExceptionForLastError ();
176 				}
177 				try {
178 					Native.Passwd p;
179 					while ((p = Native.Syscall.getpwent()) != null)
180 						entries.Add (new UnixUserInfo (p));
181 					if (Native.Syscall.GetLastError () != (Native.Errno) 0)
182 						UnixMarshal.ThrowExceptionForLastError ();
183 				}
184 				finally {
185 					Native.Syscall.endpwent ();
186 				}
187 			}
188 			return (UnixUserInfo[]) entries.ToArray (typeof(UnixUserInfo));
189 		}
190 	}
191 }
192 
193 // vim: noexpandtab
194