1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 #  include "config.h"
28 #endif
29 
30 #include <sys/types.h>
31 
32 #if defined (HAVE_PWD_H)
33 #  include <pwd.h>
34 #endif
35 
36 #include "lo-error.h"
37 #include "oct-passwd.h"
38 
39 #define NOT_SUPPORTED(nm)                       \
40   nm ": not supported on this system"
41 
42 OCTAVE_NORETURN static
43 void
err_invalid(void)44 err_invalid (void)
45 {
46   (*current_liboctave_error_handler) ("invalid password object");
47 }
48 
49 namespace octave
50 {
51   namespace sys
52   {
53     std::string
name(void) const54     password::name (void) const
55     {
56       if (! ok ())
57         err_invalid ();
58 
59       return m_name;
60     }
61 
62     std::string
passwd(void) const63     password::passwd (void) const
64     {
65       if (! ok ())
66         err_invalid ();
67 
68       return m_passwd;
69     }
70 
71     uid_t
uid(void) const72     password::uid (void) const
73     {
74       if (! ok ())
75         err_invalid ();
76 
77       return m_uid;
78     }
79 
80     gid_t
gid(void) const81     password::gid (void) const
82     {
83       if (! ok ())
84         err_invalid ();
85 
86       return m_gid;
87     }
88 
89     std::string
gecos(void) const90     password::gecos (void) const
91     {
92       if (! ok ())
93         err_invalid ();
94 
95       return m_gecos;
96     }
97 
98     std::string
dir(void) const99     password::dir (void) const
100     {
101       if (! ok ())
102         err_invalid ();
103 
104       return m_dir;
105     }
106 
107     std::string
shell(void) const108     password::shell (void) const
109     {
110       if (! ok ())
111         err_invalid ();
112 
113       return m_shell;
114     }
115 
116     password
getpwent(void)117     password::getpwent (void)
118     {
119       std::string msg;
120       return getpwent (msg);
121     }
122 
123     password
getpwent(std::string & msg)124     password::getpwent (std::string& msg)
125     {
126 #if defined HAVE_GETPWENT
127       msg = "";
128       return password (::getpwent (), msg);
129 #else
130       msg = NOT_SUPPORTED ("getpwent");
131       return password ();
132 #endif
133     }
134 
135     password
getpwuid(uid_t uid)136     password::getpwuid (uid_t uid)
137     {
138       std::string msg;
139       return getpwuid (uid, msg);
140     }
141 
142     password
getpwuid(uid_t uid,std::string & msg)143     password::getpwuid (uid_t uid, std::string& msg)
144     {
145 #if defined (HAVE_GETPWUID)
146       msg = "";
147       return password (::getpwuid (uid), msg);
148 #else
149       octave_unused_parameter (uid);
150 
151       msg = NOT_SUPPORTED ("getpwuid");
152       return password ();
153 #endif
154     }
155 
156     password
getpwnam(const std::string & nm)157     password::getpwnam (const std::string& nm)
158     {
159       std::string msg;
160       return getpwnam (nm, msg);
161     }
162 
163     password
getpwnam(const std::string & nm,std::string & msg)164     password::getpwnam (const std::string& nm, std::string& msg)
165     {
166 #if defined (HAVE_GETPWNAM)
167       msg = "";
168       return password (::getpwnam (nm.c_str ()), msg);
169 #else
170       octave_unused_parameter (nm);
171 
172       msg = NOT_SUPPORTED ("getpwnam");
173       return password ();
174 #endif
175     }
176 
177     int
setpwent(void)178     password::setpwent (void)
179     {
180       std::string msg;
181       return setpwent (msg);
182     }
183 
184     int
setpwent(std::string & msg)185     password::setpwent (std::string& msg)
186     {
187 #if defined (HAVE_SETPWENT)
188       msg = "";
189       ::setpwent ();
190       return 0;
191 #else
192       msg = NOT_SUPPORTED ("setpwent");
193       return -1;
194 #endif
195     }
196 
197     int
endpwent(void)198     password::endpwent (void)
199     {
200       std::string msg;
201       return endpwent (msg);
202     }
203 
204     int
endpwent(std::string & msg)205     password::endpwent (std::string& msg)
206     {
207 #if defined (HAVE_ENDPWENT)
208       msg = "";
209       ::endpwent ();
210       return 0;
211 #else
212       msg = NOT_SUPPORTED ("endpwent");
213       return -1;
214 #endif
215     }
216 
password(void * p,std::string & msg)217     password::password (void *p, std::string& msg)
218       : m_name (), m_passwd (), m_uid (0), m_gid (0), m_gecos (),
219         m_dir (), m_shell (), valid (false)
220     {
221 #if defined (HAVE_PWD_H)
222       msg = "";
223 
224       if (p)
225         {
226           struct ::passwd *pw = static_cast<struct ::passwd *> (p);
227 
228           m_name = pw->pw_name;
229           m_passwd = pw->pw_passwd;
230           m_uid = pw->pw_uid;
231           m_gid = pw->pw_gid;
232           m_gecos = pw->pw_gecos;
233           m_dir = pw->pw_dir;
234           m_shell = pw->pw_shell;
235 
236           valid = true;
237         }
238 #else
239       octave_unused_parameter (p);
240 
241       msg = NOT_SUPPORTED ("password functions");
242 #endif
243     }
244   }
245 }
246