1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 /* Solaris 8 has no C99 stdint.h, and Solaris generally seems not to miss it for
24 #if !defined __SUNPRO_C
30 #include <osl/security.h>
31 #include <osl/diagnose.h>
32 #include <rtl/bootstrap.h>
34 #include "osl/thread.h"
37 #if defined LINUX || defined SOLARIS
44 #define getpwuid_r(uid, pwd, buf, buflen, result) (*(result) = getpwuid(uid), (*(result) ? (memcpy (buf, *(result), sizeof (struct passwd)), 0) : errno))
48 static oslSecurityError SAL_CALL
49 osl_psz_loginUser(const sal_Char
* pszUserName
, const sal_Char
* pszPasswd
,
50 oslSecurity
* pSecurity
);
51 sal_Bool SAL_CALL
osl_psz_getUserIdent(oslSecurity Security
, sal_Char
*pszIdent
, sal_uInt32 nMax
);
52 static sal_Bool SAL_CALL
osl_psz_getUserName(oslSecurity Security
, sal_Char
* pszName
, sal_uInt32 nMax
);
53 static sal_Bool SAL_CALL
osl_psz_getHomeDir(oslSecurity Security
, sal_Char
* pszDirectory
, sal_uInt32 nMax
);
54 static sal_Bool SAL_CALL
osl_psz_getConfigDir(oslSecurity Security
, sal_Char
* pszDirectory
, sal_uInt32 nMax
);
56 static sal_Bool
sysconf_SC_GETPW_R_SIZE_MAX(size_t * value
) {
57 #if defined _SC_GETPW_R_SIZE_MAX
60 m
= sysconf(_SC_GETPW_R_SIZE_MAX
);
62 /* _SC_GETPW_R_SIZE_MAX has no limit; some platforms like certain
63 FreeBSD versions support sysconf(_SC_GETPW_R_SIZE_MAX) in a broken
64 way and always set EINVAL, so be resilient here: */
67 OSL_ASSERT(m
>= 0 && (unsigned long) m
< SIZE_MAX
);
72 /* some platforms like Mac OS X 1.3 do not define _SC_GETPW_R_SIZE_MAX: */
77 static oslSecurityImpl
* growSecurityImpl(
78 oslSecurityImpl
* impl
, size_t * bufSize
)
81 oslSecurityImpl
* p
= NULL
;
83 if (!sysconf_SC_GETPW_R_SIZE_MAX(&n
)) {
84 /* choose something sensible (the callers of growSecurityImpl will
85 detect it if the allocated buffer is too small: */
88 } else if (*bufSize
<= SIZE_MAX
/ 2) {
92 if (n
<= SIZE_MAX
- offsetof(oslSecurityImpl
, m_buffer
)) {
94 n
+= offsetof(oslSecurityImpl
, m_buffer
);
96 *bufSize
= SIZE_MAX
- offsetof(oslSecurityImpl
, m_buffer
);
108 static void deleteSecurityImpl(oslSecurityImpl
* impl
) {
112 oslSecurity SAL_CALL
osl_getCurrentSecurity()
115 oslSecurityImpl
* p
= NULL
;
117 struct passwd
* found
;
118 p
= growSecurityImpl(p
, &n
);
122 switch (getpwuid_r(getuid(), &p
->m_pPasswd
, p
->m_buffer
, n
, &found
)) {
131 deleteSecurityImpl(p
);
137 oslSecurityError SAL_CALL
osl_loginUser(
138 rtl_uString
*ustrUserName
,
139 rtl_uString
*ustrPassword
,
140 oslSecurity
*pSecurity
143 oslSecurityError Error
;
144 rtl_String
* strUserName
=0;
145 rtl_String
* strPassword
=0;
146 sal_Char
* pszUserName
=0;
147 sal_Char
* pszPassword
=0;
149 if ( ustrUserName
!= 0 )
151 rtl_uString2String( &strUserName
,
152 rtl_uString_getStr(ustrUserName
),
153 rtl_uString_getLength(ustrUserName
),
154 RTL_TEXTENCODING_UTF8
,
155 OUSTRING_TO_OSTRING_CVTFLAGS
);
156 pszUserName
= rtl_string_getStr(strUserName
);
160 if ( ustrPassword
!= 0 )
162 rtl_uString2String( &strPassword
,
163 rtl_uString_getStr(ustrPassword
),
164 rtl_uString_getLength(ustrPassword
),
165 RTL_TEXTENCODING_UTF8
,
166 OUSTRING_TO_OSTRING_CVTFLAGS
);
167 pszPassword
= rtl_string_getStr(strPassword
);
171 Error
=osl_psz_loginUser(pszUserName
,pszPassword
,pSecurity
);
173 if ( strUserName
!= 0 )
175 rtl_string_release(strUserName
);
180 rtl_string_release(strPassword
);
188 static oslSecurityError SAL_CALL
189 osl_psz_loginUser(const sal_Char
* pszUserName
, const sal_Char
* pszPasswd
,
190 oslSecurity
* pSecurity
)
196 return osl_Security_E_None
;
199 oslSecurityError SAL_CALL
osl_loginUserOnFileServer(
200 rtl_uString
*strUserName
,
201 rtl_uString
*strPasswd
,
202 rtl_uString
*strFileServer
,
203 oslSecurity
*pSecurity
206 (void) strUserName
; /* unused */
207 (void) strPasswd
; /* unused */
208 (void) strFileServer
; /* unused */
209 (void) pSecurity
; /* unused */
210 return osl_Security_E_UserUnknown
;
214 sal_Bool SAL_CALL
osl_getUserIdent(oslSecurity Security
, rtl_uString
**ustrIdent
)
216 sal_Bool bRet
=sal_False
;
217 sal_Char pszIdent
[1024];
221 bRet
= osl_psz_getUserIdent(Security
,pszIdent
,sizeof(pszIdent
));
223 rtl_string2UString( ustrIdent
, pszIdent
, rtl_str_getLength( pszIdent
), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
);
224 OSL_ASSERT(*ustrIdent
!= NULL
);
230 sal_Bool SAL_CALL
osl_psz_getUserIdent(oslSecurity Security
, sal_Char
*pszIdent
, sal_uInt32 nMax
)
235 oslSecurityImpl
*pSecImpl
= (oslSecurityImpl
*)Security
;
237 if (pSecImpl
== NULL
)
240 nChr
= snprintf(buffer
, sizeof(buffer
), "%u", pSecImpl
->m_pPasswd
.pw_uid
);
241 if ( nChr
< 0 || SAL_INT_CAST(sal_uInt32
, nChr
) >= sizeof(buffer
)
242 || SAL_INT_CAST(sal_uInt32
, nChr
) >= nMax
)
243 return sal_False
; /* leave *pszIdent unmodified in case of failure */
245 memcpy(pszIdent
, buffer
, nChr
+1);
249 sal_Bool SAL_CALL
osl_getUserName(oslSecurity Security
, rtl_uString
**ustrName
)
251 sal_Bool bRet
=sal_False
;
252 sal_Char pszName
[1024];
256 bRet
= osl_psz_getUserName(Security
,pszName
,sizeof(pszName
));
258 rtl_string2UString( ustrName
, pszName
, rtl_str_getLength( pszName
), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
);
259 OSL_ASSERT(*ustrName
!= NULL
);
266 static sal_Bool SAL_CALL
osl_psz_getUserName(oslSecurity Security
, sal_Char
* pszName
, sal_uInt32 nMax
)
268 oslSecurityImpl
*pSecImpl
= (oslSecurityImpl
*)Security
;
270 if (pSecImpl
== NULL
|| pSecImpl
->m_pPasswd
.pw_name
== NULL
)
273 strncpy(pszName
, pSecImpl
->m_pPasswd
.pw_name
, nMax
);
278 sal_Bool SAL_CALL
osl_getHomeDir(oslSecurity Security
, rtl_uString
**pustrDirectory
)
280 sal_Bool bRet
=sal_False
;
281 sal_Char pszDirectory
[PATH_MAX
];
283 pszDirectory
[0] = '\0';
285 bRet
= osl_psz_getHomeDir(Security
,pszDirectory
,sizeof(pszDirectory
));
287 if ( bRet
== sal_True
)
289 rtl_string2UString( pustrDirectory
, pszDirectory
, rtl_str_getLength( pszDirectory
), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
);
290 OSL_ASSERT(*pustrDirectory
!= NULL
);
291 osl_getFileURLFromSystemPath( *pustrDirectory
, pustrDirectory
);
297 static sal_Bool SAL_CALL
osl_psz_getHomeDir(oslSecurity Security
, sal_Char
* pszDirectory
, sal_uInt32 nMax
)
299 oslSecurityImpl
*pSecImpl
= (oslSecurityImpl
*)Security
;
301 if (pSecImpl
== NULL
)
306 sal_Bool bRet
= sal_False
;
307 rtl_uString
*pName
= 0, *pValue
= 0;
309 rtl_uString_newFromAscii(&pName
, "HOME");
311 if (rtl_bootstrap_get(pName
, &pValue
, NULL
))
313 rtl_String
*pStrValue
= 0;
314 if (pValue
&& pValue
->length
> 0)
316 rtl_uString2String(&pStrValue
, pValue
->buffer
,
317 pValue
->length
, RTL_TEXTENCODING_UTF8
,
318 OUSTRING_TO_OSTRING_CVTFLAGS
);
319 if (pStrValue
&& pStrValue
->length
> 0)
321 sal_Int32 nCopy
= (sal_Int32
)(nMax
-1) < pStrValue
->length
? (sal_Int32
)(nMax
-1) : pStrValue
->length
;
322 strncpy (pszDirectory
, pStrValue
->buffer
, nCopy
);
323 pszDirectory
[nCopy
] = '\0';
324 bRet
= (size_t)pStrValue
->length
< nMax
;
326 rtl_string_release(pStrValue
);
328 rtl_uString_release(pName
);
335 /* if current user, check also environment for HOME */
336 if (getuid() == pSecImpl
->m_pPasswd
.pw_uid
)
338 sal_Char
*pStr
= NULL
;
345 #ifdef _POSIX_PTHREAD_SEMANTICS
346 if ( 0 != getpwuid_r(getuid(), &pwd
, buffer
, sizeof(buffer
), &ppwd
) )
349 ppwd
= getpwuid_r(getuid(), &pwd
, buffer
, sizeof(buffer
) );
355 pStr
= getenv("HOME");
358 if (pStr
!= NULL
&& strlen(pStr
) > 0 && access(pStr
, 0) == 0)
359 strncpy(pszDirectory
, pStr
, nMax
);
360 else if (pSecImpl
->m_pPasswd
.pw_dir
!= NULL
)
361 strncpy(pszDirectory
, pSecImpl
->m_pPasswd
.pw_dir
, nMax
);
365 else if (pSecImpl
->m_pPasswd
.pw_dir
!= NULL
)
366 strncpy(pszDirectory
, pSecImpl
->m_pPasswd
.pw_dir
, nMax
);
373 sal_Bool SAL_CALL
osl_getConfigDir(oslSecurity Security
, rtl_uString
**pustrDirectory
)
375 sal_Bool bRet
= sal_False
;
376 sal_Char pszDirectory
[PATH_MAX
];
378 pszDirectory
[0] = '\0';
380 bRet
= osl_psz_getConfigDir(Security
,pszDirectory
,sizeof(pszDirectory
));
382 if ( bRet
== sal_True
)
384 rtl_string2UString( pustrDirectory
, pszDirectory
, rtl_str_getLength( pszDirectory
), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
);
385 OSL_ASSERT(*pustrDirectory
!= NULL
);
386 osl_getFileURLFromSystemPath( *pustrDirectory
, pustrDirectory
);
392 #if !defined(MACOSX) && !defined(IOS)
394 #define DOT_CONFIG "/.config"
396 static sal_Bool SAL_CALL
osl_psz_getConfigDir(oslSecurity Security
, sal_Char
* pszDirectory
, sal_uInt32 nMax
)
398 sal_Char
*pStr
= getenv("XDG_CONFIG_HOME");
400 if (pStr
== NULL
|| strlen(pStr
) == 0 || access(pStr
, 0) != 0)
403 // a default equal to $HOME/.config should be used.
404 if (!osl_psz_getHomeDir(Security
, pszDirectory
, nMax
))
406 n
= strlen(pszDirectory
);
407 if (n
+ sizeof(DOT_CONFIG
) < nMax
)
409 strncpy(pszDirectory
+n
, DOT_CONFIG
, sizeof(DOT_CONFIG
));
410 if (access(pszDirectory
, 0) != 0)
413 pszDirectory
[n
] = '\0';
418 strncpy(pszDirectory
, pStr
, nMax
);
428 * FIXME: rewrite to use more flexible
429 * NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)
430 * as soon as we can bumb the baseline to Tiger (for NSApplicationSupportDirectory) and have
431 * support for Objective-C in the build environment
434 #define MACOSX_CONFIG_DIR "/Library/Application Support" /* Used on iOS, too */
435 static sal_Bool SAL_CALL
osl_psz_getConfigDir(oslSecurity Security
, sal_Char
* pszDirectory
, sal_uInt32 nMax
)
437 if( osl_psz_getHomeDir(Security
, pszDirectory
, nMax
- sizeof(MACOSX_CONFIG_DIR
) + 1) )
439 strcat( pszDirectory
, MACOSX_CONFIG_DIR
);
448 sal_Bool SAL_CALL
osl_isAdministrator(oslSecurity Security
)
450 oslSecurityImpl
*pSecImpl
= (oslSecurityImpl
*)Security
;
452 if (pSecImpl
== NULL
)
455 if (pSecImpl
->m_pPasswd
.pw_uid
!= 0)
461 void SAL_CALL
osl_freeSecurityHandle(oslSecurity Security
)
463 deleteSecurityImpl(Security
);
467 sal_Bool SAL_CALL
osl_loadUserProfile(oslSecurity Security
)
469 (void) Security
; /* unused */
473 void SAL_CALL
osl_unloadUserProfile(oslSecurity Security
)
475 (void) Security
; /* unused */
478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */