1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <stddef.h>
25
26 /* Solaris 8 has no C99 stdint.h, and Solaris generally seems not to miss it for
27 SIZE_MAX: */
28 #if !defined __SUNPRO_C
29 #include <stdint.h>
30 #endif
31
32 #include "system.h"
33
34 #include <osl/security.h>
35 #include <osl/diagnose.h>
36
37 #include "osl/thread.h"
38 #include "osl/file.h"
39
40 #if defined LINUX || defined SOLARIS
41 #include <crypt.h>
42 #endif
43
44 #include "secimpl.h"
45
46 #ifndef NOPAM
47 #ifndef PAM_BINARY_MSG
48 #define PAM_BINARY_MSG 6
49 #endif
50 #endif
51
52 static oslSecurityError SAL_CALL
53 osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd,
54 oslSecurity* pSecurity);
55 sal_Bool SAL_CALL osl_psz_getUserIdent(oslSecurity Security, sal_Char *pszIdent, sal_uInt32 nMax);
56 static sal_Bool SAL_CALL osl_psz_getUserName(oslSecurity Security, sal_Char* pszName, sal_uInt32 nMax);
57 static sal_Bool SAL_CALL osl_psz_getHomeDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax);
58 static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax);
59
sysconf_SC_GETPW_R_SIZE_MAX(size_t * value)60 static sal_Bool sysconf_SC_GETPW_R_SIZE_MAX(size_t * value) {
61 #if defined _SC_GETPW_R_SIZE_MAX
62 long m;
63 errno = 0;
64 m = sysconf(_SC_GETPW_R_SIZE_MAX);
65 if (m == -1) {
66 /* _SC_GETPW_R_SIZE_MAX has no limit; some platforms like certain
67 FreeBSD versions support sysconf(_SC_GETPW_R_SIZE_MAX) in a broken
68 way and always set EINVAL, so be resilient here: */
69 return sal_False;
70 } else {
71 OSL_ASSERT(m >= 0 && (unsigned long) m < SIZE_MAX);
72 *value = (size_t) m;
73 return sal_True;
74 }
75 #else
76 /* some platforms like Mac OS X 1.3 do not define _SC_GETPW_R_SIZE_MAX: */
77 return sal_False;
78 #endif
79 }
80
growSecurityImpl(oslSecurityImpl * impl,size_t * bufSize)81 static oslSecurityImpl * growSecurityImpl(
82 oslSecurityImpl * impl, size_t * bufSize)
83 {
84 size_t n = 0;
85 oslSecurityImpl * p = NULL;
86 if (impl == NULL) {
87 if (!sysconf_SC_GETPW_R_SIZE_MAX(&n)) {
88 /* choose something sensible (the callers of growSecurityImpl will
89 detect it if the allocated buffer is too small: */
90 n = 1024;
91 }
92 } else if (*bufSize <= SIZE_MAX / 2) {
93 n = 2 * *bufSize;
94 }
95 if (n != 0) {
96 if (n <= SIZE_MAX - offsetof(oslSecurityImpl, m_buffer)) {
97 *bufSize = n;
98 n += offsetof(oslSecurityImpl, m_buffer);
99 } else {
100 *bufSize = SIZE_MAX - offsetof(oslSecurityImpl, m_buffer);
101 n = SIZE_MAX;
102 }
103 p = realloc(impl, n);
104 }
105 if (p == NULL) {
106 free(impl);
107 }
108 return p;
109 }
110
deleteSecurityImpl(oslSecurityImpl * impl)111 static void deleteSecurityImpl(oslSecurityImpl * impl) {
112 free(impl);
113 }
114
osl_getCurrentSecurity()115 oslSecurity SAL_CALL osl_getCurrentSecurity()
116 {
117 size_t n = 0;
118 oslSecurityImpl * p = NULL;
119 for (;;) {
120 struct passwd * found;
121 p = growSecurityImpl(p, &n);
122 if (p == NULL) {
123 return NULL;
124 }
125 switch (getpwuid_r(getuid(), &p->m_pPasswd, p->m_buffer, n, &found)) {
126 case ERANGE:
127 break;
128 case 0:
129 if (found != NULL) {
130 return p;
131 }
132 /* fall through */
133 default:
134 deleteSecurityImpl(p);
135 return NULL;
136 }
137 }
138 }
139
140
141 #if defined LINUX && !defined NOPAM
142
143 /*
144 *
145 * osl Routines for Pluggable Authentication Modules (PAM)
146 * tested with Linux-PAM 0.66 on Redhat-6.0 and
147 * Linux-PAM 0.64 on RedHat-5.2,
148 * XXX Will probably not run on PAM 0.59 or prior, since
149 * number of pam_response* responses has changed
150 *
151 */
152
153 #include <security/pam_appl.h>
154
155 typedef struct {
156 char* name;
157 char* password;
158 } sal_PamData;
159
160 typedef struct {
161 int (*pam_start)(const char *service_name, const char *user,
162 const struct pam_conv *pam_conversation,
163 pam_handle_t **pamh);
164 int (*pam_end) (pam_handle_t *pamh, int pam_status);
165 int (*pam_authenticate) (pam_handle_t *pamh, int flags);
166 int (*pam_acct_mgmt) (pam_handle_t *pamh, int flags);
167 } sal_PamModule;
168
169 /*
170 * Implement a pam-conversation callback-routine,
171 * it just supply name and password instead of prompting the user.
172 * I guess that echo-off means 'ask for password' and echo-on means
173 * 'ask for user-name'. In fact I've never been asked anything else
174 * than the password
175 * XXX Please notice that if a pam-module does ask anything else, we
176 * are completely lost, and a pam-module is free to do so
177 * XXX
178 */
179
180 static int
osl_PamConversation(int num_msg,const struct pam_message ** msgm,struct pam_response ** response,void * appdata_ptr)181 osl_PamConversation (int num_msg, const struct pam_message **msgm,
182 struct pam_response **response, void *appdata_ptr)
183 {
184 int i;
185 sal_Bool error;
186 sal_PamData *pam_data;
187 struct pam_response *p_reply;
188
189 /* resource initialization */
190 pam_data = (sal_PamData*) appdata_ptr;
191 p_reply = (struct pam_response *) calloc( num_msg,
192 sizeof(struct pam_response));
193 if ( p_reply == NULL || pam_data == NULL )
194 {
195 if ( p_reply != NULL )
196 free ( p_reply );
197 *response = NULL;
198 return PAM_CONV_ERR;
199 }
200
201 /* pseudo dialog */
202 error = sal_False;
203 for ( i = 0; i < num_msg ; i++ )
204 {
205 switch ( msgm[ i ]->msg_style )
206 {
207 case PAM_PROMPT_ECHO_OFF:
208 p_reply[ i ].resp_retcode = 0;
209 p_reply[ i ].resp = strdup( pam_data->password );
210 break;
211 case PAM_PROMPT_ECHO_ON:
212 p_reply[ i ].resp_retcode = 0;
213 p_reply[ i ].resp = strdup( pam_data->name );
214 break;
215 case PAM_ERROR_MSG:
216 case PAM_TEXT_INFO:
217 case PAM_BINARY_PROMPT:
218 case PAM_BINARY_MSG:
219 p_reply[ i ].resp_retcode = 0;
220 p_reply[ i ].resp = NULL;
221 break;
222 default:
223 error = sal_True;
224 break;
225 }
226 }
227
228 /* free resources on error */
229 if ( error )
230 {
231 for ( i = 0; i < num_msg ; i++ )
232 if ( p_reply[ i ].resp )
233 {
234 memset ( p_reply[ i ].resp, 0,
235 strlen( p_reply[ i ].resp ) );
236 free ( p_reply[ i ].resp );
237 }
238 free ( p_reply );
239
240 *response = NULL;
241 return PAM_CONV_ERR;
242 }
243
244 /* well done */
245 *response = p_reply;
246 return PAM_SUCCESS;
247 }
248
249 #ifndef PAM_LINK
250 /*
251 * avoid linking against libpam.so, since it is not available on all systems,
252 * instead load-on-call, returns structure which holds pointer to
253 * pam-functions,
254 * library is never closed in case of success
255 */
256
osl_getPAM()257 static sal_PamModule* osl_getPAM()
258 {
259 static sal_PamModule *pam_module = NULL;
260 static sal_Bool load_once = sal_False;
261
262 if ( !load_once )
263 {
264 /* get library-handle. cannot use osl-module, since
265 RTLD_GLOBAL is required for PAM-0.64 RH 5.2
266 (but not for PAM-0.66 RH 6.0) */
267 void *pam_hdl;
268
269 pam_hdl = dlopen( "libpam.so.0", RTLD_GLOBAL | RTLD_LAZY );
270
271 if ( pam_hdl != NULL )
272 pam_module = (sal_PamModule*)calloc( 1, sizeof(sal_PamModule) );
273
274 /* load functions */
275 if ( pam_module != NULL )
276 {
277 pam_module->pam_acct_mgmt = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_acct_mgmt" );
278 pam_module->pam_authenticate
279 = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_authenticate" );
280 pam_module->pam_end = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_end" );
281 pam_module->pam_start = (int (*)(const char *, const char *, const struct pam_conv *, pam_handle_t **)) dlsym ( pam_hdl, "pam_start" );
282
283 /* free resources, if not completely successful */
284 if ( (pam_module->pam_start == NULL)
285 || (pam_module->pam_end == NULL)
286 || (pam_module->pam_authenticate == NULL)
287 || (pam_module->pam_acct_mgmt == NULL) )
288 {
289 free( pam_module );
290 pam_module = NULL;
291 dlclose( pam_hdl );
292 }
293 }
294
295 /* never try again */
296 load_once = sal_True;
297 }
298
299 return pam_module;
300 }
301 #endif
302
303 /*
304 * User Identification using PAM
305 */
306
307 static sal_Bool
osl_PamAuthentification(const sal_Char * name,const sal_Char * password)308 osl_PamAuthentification( const sal_Char* name, const sal_Char* password )
309 {
310 sal_Bool success = sal_False;
311
312 #ifndef PAM_LINK
313 sal_PamModule* pam_module;
314
315 pam_module = osl_getPAM();
316 if ( pam_module != NULL )
317 {
318 #endif
319 pam_handle_t *pam_handle = NULL;
320 struct pam_conv pam_conversation;
321 sal_PamData pam_data;
322
323 int return_value;
324
325 pam_data.name = (char*) name;
326 pam_data.password = (char*) password;
327
328 pam_conversation.conv = osl_PamConversation;
329 pam_conversation.appdata_ptr = (void*)(&pam_data);
330
331 #ifndef PAM_LINK
332 return_value = pam_module->pam_start( "su", name,
333 &pam_conversation, &pam_handle);
334 #else
335 return_value = pam_start( "su", name,
336 &pam_conversation, &pam_handle);
337 #endif
338 if (return_value == PAM_SUCCESS )
339 #ifndef PAM_LINK
340 return_value = pam_module->pam_authenticate(pam_handle, 0);
341 #else
342 return_value = pam_authenticate(pam_handle, 0);
343 #endif
344 if (return_value == PAM_SUCCESS )
345 #ifndef PAM_LINK
346 return_value = pam_module->pam_acct_mgmt(pam_handle, 0);
347 pam_module->pam_end( pam_handle, return_value );
348 #else
349 return_value = pam_acct_mgmt(pam_handle, 0);
350 pam_end( pam_handle, return_value );
351 #endif
352
353 success = (sal_Bool)(return_value == PAM_SUCCESS);
354 #ifndef PAM_LINK
355 }
356 #endif
357
358 return success;
359 }
360
361
362 #ifndef CRYPT_LINK
363 /* dummy crypt, matches the interface of
364 crypt() but does not encrypt at all */
365 static const sal_Char* SAL_CALL
osl_noCrypt(const sal_Char * key,const sal_Char * salt)366 osl_noCrypt ( const sal_Char *key, const sal_Char *salt )
367 {
368 (void) salt; /* unused */
369 return key;
370 }
371
372 /* load-on-call crypt library and crypt symbol */
373 static void* SAL_CALL
osl_getCrypt()374 osl_getCrypt()
375 {
376 static char* (*crypt_sym)(const char*, const char*) = NULL;
377 static sal_Bool load_once = sal_False;
378
379 if ( !load_once )
380 {
381 void * crypt_library;
382
383 crypt_library = dlopen( "libcrypt.so.1", RTLD_GLOBAL | RTLD_LAZY ); /* never closed */
384 if ( crypt_library != NULL )
385 crypt_sym = (char* (*)(const char *, const char *)) dlsym(crypt_library, "crypt" );
386 if ( crypt_sym == NULL ) /* no libcrypt or libcrypt without crypt */
387 crypt_sym = (char* (*)(const char *, const char *)) &osl_noCrypt;
388
389 load_once = sal_True;
390 }
391
392 return (void*)crypt_sym;
393 }
394
395 /* replacement for crypt function for password encryption, uses either
396 strong encryption of dlopen'ed libcrypt.so.1 or dummy implementation
397 with no encryption. Objective target is to avoid linking against
398 libcrypt (not available on caldera open linux 2.2 #63822#) */
399 static sal_Char* SAL_CALL
osl_dynamicCrypt(const sal_Char * key,const sal_Char * salt)400 osl_dynamicCrypt ( const sal_Char *key, const sal_Char *salt )
401 {
402 char* (*dynamic_crypt)(char *, char *);
403
404 dynamic_crypt = (char * (*)(char *, char *)) osl_getCrypt();
405
406 return dynamic_crypt( (sal_Char*)key, (sal_Char*)salt );
407 }
408 #endif
409
410 /*
411 * compare an encrypted and an unencrypted password for equality
412 * returns true if passwords are equal, false otherwise
413 * Note: uses crypt() and a mutex instead of crypt_r() since crypt_r needs
414 * more than 128KByte of external buffer for struct crypt_data
415 */
416
417 static sal_Bool SAL_CALL
osl_equalPasswords(const sal_Char * pEncryptedPassword,const sal_Char * pPlainPassword)418 osl_equalPasswords ( const sal_Char *pEncryptedPassword, const sal_Char *pPlainPassword )
419 {
420 static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER;
421
422 sal_Bool success;
423 sal_Char salt[3];
424 sal_Char *encrypted_plain;
425
426 salt[0] = pEncryptedPassword[0];
427 salt[1] = pEncryptedPassword[1];
428 salt[2] = '\0';
429
430 pthread_mutex_lock(&crypt_mutex);
431
432 #ifndef CRYPT_LINK
433 encrypted_plain = (sal_Char *)osl_dynamicCrypt( pPlainPassword, salt );
434 #else
435 encrypted_plain = (sal_Char *)crypt( pPlainPassword, salt );
436 #endif
437 success = (sal_Bool) (strcmp(pEncryptedPassword, encrypted_plain) == 0);
438
439 pthread_mutex_unlock(&crypt_mutex);
440
441 return success;
442 }
443
444 #endif /* defined LINUX && !defined NOPAM */
osl_loginUser(rtl_uString * ustrUserName,rtl_uString * ustrPassword,oslSecurity * pSecurity)445 oslSecurityError SAL_CALL osl_loginUser(
446 rtl_uString *ustrUserName,
447 rtl_uString *ustrPassword,
448 oslSecurity *pSecurity
449 )
450 {
451 oslSecurityError Error;
452 rtl_String* strUserName=0;
453 rtl_String* strPassword=0;
454 sal_Char* pszUserName=0;
455 sal_Char* pszPassword=0;
456
457 if ( ustrUserName != 0 )
458 {
459
460 rtl_uString2String( &strUserName,
461 rtl_uString_getStr(ustrUserName),
462 rtl_uString_getLength(ustrUserName),
463 RTL_TEXTENCODING_UTF8,
464 OUSTRING_TO_OSTRING_CVTFLAGS );
465 pszUserName = rtl_string_getStr(strUserName);
466 }
467
468
469 if ( ustrPassword != 0 )
470 {
471 rtl_uString2String( &strPassword,
472 rtl_uString_getStr(ustrPassword),
473 rtl_uString_getLength(ustrPassword),
474 RTL_TEXTENCODING_UTF8,
475 OUSTRING_TO_OSTRING_CVTFLAGS );
476 pszPassword = rtl_string_getStr(strPassword);
477 }
478
479
480 Error=osl_psz_loginUser(pszUserName,pszPassword,pSecurity);
481
482 if ( strUserName != 0 )
483 {
484 rtl_string_release(strUserName);
485 }
486
487 if ( strPassword)
488 {
489 rtl_string_release(strPassword);
490 }
491
492
493 return Error;
494 }
495
496
497 static oslSecurityError SAL_CALL
osl_psz_loginUser(const sal_Char * pszUserName,const sal_Char * pszPasswd,oslSecurity * pSecurity)498 osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd,
499 oslSecurity* pSecurity)
500 {
501 #if defined NETBSD || defined SCO || defined AIX || defined FREEBSD || \
502 defined MACOSX
503
504 return osl_Security_E_None;
505
506 #else
507
508 oslSecurityError nError = osl_Security_E_Unknown;
509 oslSecurityImpl * p = NULL;
510 if (pszUserName != NULL && pszPasswd != NULL && pSecurity != NULL) {
511 /* get nis or normal password, should succeed for any known user, but
512 perhaps the password is wrong (i.e. 'x') if shadow passwords are in
513 use or authentication must be done by PAM */
514 size_t n = 0;
515 int err = 0;
516 struct passwd * found = NULL;
517 for (;;) {
518 p = growSecurityImpl(p, &n);
519 if (p == NULL) {
520 break;
521 }
522 err = getpwnam_r(
523 pszUserName, &p->m_pPasswd, p->m_buffer, n, &found);
524 if (err != ERANGE) {
525 break;
526 }
527 }
528 if (p != NULL && err == 0) {
529 if (found == NULL) {
530 nError = osl_Security_E_UserUnknown;
531 } else {
532 #if defined LINUX && !defined NOPAM
533 /* only root is able to read the /etc/shadow passwd, a normal
534 user even can't read his own encrypted passwd */
535 if (osl_equalPasswords(p->m_pPasswd.pw_passwd, pszPasswd) ||
536 osl_PamAuthentification(pszUserName, pszPasswd))
537 {
538 nError = osl_Security_E_None;
539 } else {
540 char buffer[1024];
541 struct spwd result_buf;
542 struct spwd * pShadowPasswd;
543 buffer[0] = '\0';
544 if (getspnam_r(
545 pszUserName, &result_buf, buffer, sizeof buffer,
546 &pShadowPasswd) == 0 &&
547 pShadowPasswd != NULL)
548 {
549 nError =
550 osl_equalPasswords(
551 pShadowPasswd->sp_pwdp, pszPasswd)
552 ? osl_Security_E_None
553 : osl_Security_E_WrongPassword;
554 } else if (getuid() == 0) {
555 /* mfe: Try to verify the root-password via nis */
556 if (getspnam_r(
557 "root", &result_buf, buffer, sizeof buffer,
558 &pShadowPasswd) == 0 &&
559 pShadowPasswd != NULL &&
560 osl_equalPasswords(
561 pShadowPasswd->sp_pwdp, pszPasswd))
562 {
563 nError = osl_Security_E_None;
564 } else {
565 /* mfe: we can't get via nis (glibc2.0.x has bug in
566 getspnam_r) we try it with the normal getspnam */
567 static pthread_mutex_t pwmutex =
568 PTHREAD_MUTEX_INITIALIZER;
569 pthread_mutex_lock(&pwmutex);
570 pShadowPasswd = getspnam("root");
571 pthread_mutex_unlock(&pwmutex);
572 nError =
573 ((pShadowPasswd != NULL &&
574 osl_equalPasswords(
575 pShadowPasswd->sp_pwdp, pszPasswd)) ||
576 osl_PamAuthentification("root", pszPasswd))
577 ? osl_Security_E_None
578 : osl_Security_E_WrongPassword;
579 }
580 }
581 }
582 #else
583 char buffer[1024];
584 struct spwd spwdStruct;
585 buffer[0] = '\0';
586 #ifdef OLD_SHADOW_API
587 if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer) != NULL)
588 #else
589 if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer, NULL) == 0)
590 #endif
591 {
592 char salt[3];
593 char * cryptPasswd;
594 strncpy(salt, spwdStruct.sp_pwdp, 2);
595 salt[2] = '\0';
596 cryptPasswd = (char *) crypt(pszPasswd, salt);
597 if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) {
598 nError = osl_Security_E_None;
599 } else if (getuid() == 0 &&
600 #ifdef OLD_SHADOW_API
601 (getspnam_r("root", &spwdStruct, buffer, sizeof buffer) != NULL))
602 #else
603 (getspnam_r("root", &spwdStruct, buffer, sizeof buffer, NULL) == 0))
604 #endif
605 {
606 /* if current process is running as root, allow to logon
607 as any other user */
608 strncpy(salt, spwdStruct.sp_pwdp, 2);
609 salt[2] = '\0';
610 cryptPasswd = (char *) crypt(pszPasswd, salt);
611 if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) {
612 nError = osl_Security_E_None;
613 }
614 } else {
615 nError = osl_Security_E_WrongPassword;
616 }
617 }
618 #endif
619 }
620 }
621 }
622 if (nError == osl_Security_E_None) {
623 *pSecurity = p;
624 } else {
625 deleteSecurityImpl(p);
626 *pSecurity = NULL;
627 }
628 return nError;
629
630 #endif
631 }
632
osl_loginUserOnFileServer(rtl_uString * strUserName,rtl_uString * strPasswd,rtl_uString * strFileServer,oslSecurity * pSecurity)633 oslSecurityError SAL_CALL osl_loginUserOnFileServer(
634 rtl_uString *strUserName,
635 rtl_uString *strPasswd,
636 rtl_uString *strFileServer,
637 oslSecurity *pSecurity
638 )
639 {
640 (void) strUserName; /* unused */
641 (void) strPasswd; /* unused */
642 (void) strFileServer; /* unused */
643 (void) pSecurity; /* unused */
644 return osl_Security_E_UserUnknown;
645 }
646
647
osl_getUserIdent(oslSecurity Security,rtl_uString ** ustrIdent)648 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **ustrIdent)
649 {
650 sal_Bool bRet=sal_False;
651 sal_Char pszIdent[1024];
652
653 pszIdent[0] = '\0';
654
655 bRet = osl_psz_getUserIdent(Security,pszIdent,sizeof(pszIdent));
656
657 rtl_string2UString( ustrIdent, pszIdent, rtl_str_getLength( pszIdent ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
658 OSL_ASSERT(*ustrIdent != NULL);
659
660 return bRet;
661 }
662
663
osl_psz_getUserIdent(oslSecurity Security,sal_Char * pszIdent,sal_uInt32 nMax)664 sal_Bool SAL_CALL osl_psz_getUserIdent(oslSecurity Security, sal_Char *pszIdent, sal_uInt32 nMax)
665 {
666 sal_Char buffer[32];
667 sal_Int32 nChr;
668
669 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
670
671 if (pSecImpl == NULL)
672 return sal_False;
673
674 nChr = snprintf(buffer, sizeof(buffer), "%u", pSecImpl->m_pPasswd.pw_uid);
675 if ( nChr < 0 || SAL_INT_CAST(sal_uInt32, nChr) >= sizeof(buffer)
676 || SAL_INT_CAST(sal_uInt32, nChr) >= nMax )
677 return sal_False; /* leave *pszIdent unmodified in case of failure */
678
679 memcpy(pszIdent, buffer, nChr+1);
680 return sal_True;
681 }
682
osl_getUserName(oslSecurity Security,rtl_uString ** ustrName)683 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **ustrName)
684 {
685 sal_Bool bRet=sal_False;
686 sal_Char pszName[1024];
687
688 pszName[0] = '\0';
689
690 bRet = osl_psz_getUserName(Security,pszName,sizeof(pszName));
691
692 rtl_string2UString( ustrName, pszName, rtl_str_getLength( pszName ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
693 OSL_ASSERT(*ustrName != NULL);
694
695 return bRet;
696 }
697
698
699
osl_psz_getUserName(oslSecurity Security,sal_Char * pszName,sal_uInt32 nMax)700 static sal_Bool SAL_CALL osl_psz_getUserName(oslSecurity Security, sal_Char* pszName, sal_uInt32 nMax)
701 {
702 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
703
704 if (pSecImpl == NULL)
705 return sal_False;
706
707 strncpy(pszName, pSecImpl->m_pPasswd.pw_name, nMax);
708
709 return sal_True;
710 }
711
osl_getHomeDir(oslSecurity Security,rtl_uString ** pustrDirectory)712 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
713 {
714 sal_Bool bRet=sal_False;
715 sal_Char pszDirectory[PATH_MAX];
716
717 pszDirectory[0] = '\0';
718
719 bRet = osl_psz_getHomeDir(Security,pszDirectory,sizeof(pszDirectory));
720
721 if ( bRet == sal_True )
722 {
723 rtl_string2UString( pustrDirectory, pszDirectory, rtl_str_getLength( pszDirectory ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
724 OSL_ASSERT(*pustrDirectory != NULL);
725 osl_getFileURLFromSystemPath( *pustrDirectory, pustrDirectory );
726 }
727
728 return bRet;
729 }
730
731
osl_psz_getHomeDir(oslSecurity Security,sal_Char * pszDirectory,sal_uInt32 nMax)732 static sal_Bool SAL_CALL osl_psz_getHomeDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
733 {
734 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
735
736 if (pSecImpl == NULL)
737 return sal_False;
738
739 /* if current user, check also environment for HOME */
740 if (getuid() == pSecImpl->m_pPasswd.pw_uid)
741 {
742 sal_Char *pStr = NULL;
743 #ifdef SOLARIS
744 char buffer[8192];
745
746 struct passwd pwd;
747 struct passwd *ppwd;
748
749 #ifdef _POSIX_PTHREAD_SEMANTICS
750 if ( 0 != getpwuid_r(getuid(), &pwd, buffer, sizeof(buffer), &ppwd ) )
751 ppwd = NULL;
752 #else
753 ppwd = getpwuid_r(getuid(), &pwd, buffer, sizeof(buffer) );
754 #endif
755
756 if ( ppwd )
757 pStr = ppwd->pw_dir;
758 #else
759 pStr = getenv("HOME");
760 #endif
761
762 if ((pStr != NULL) && (strlen(pStr) > 0) &&
763 (access(pStr, 0) == 0))
764 strncpy(pszDirectory, pStr, nMax);
765 else
766 strncpy(pszDirectory, pSecImpl->m_pPasswd.pw_dir, nMax);
767 }
768 else
769 strncpy(pszDirectory, pSecImpl->m_pPasswd.pw_dir, nMax);
770
771 return sal_True;
772 }
773
osl_getConfigDir(oslSecurity Security,rtl_uString ** pustrDirectory)774 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
775 {
776 sal_Bool bRet = sal_False;
777 sal_Char pszDirectory[PATH_MAX];
778
779 pszDirectory[0] = '\0';
780
781 bRet = osl_psz_getConfigDir(Security,pszDirectory,sizeof(pszDirectory));
782
783 if ( bRet == sal_True )
784 {
785 rtl_string2UString( pustrDirectory, pszDirectory, rtl_str_getLength( pszDirectory ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
786 OSL_ASSERT(*pustrDirectory != NULL);
787 osl_getFileURLFromSystemPath( *pustrDirectory, pustrDirectory );
788 }
789
790 return bRet;
791 }
792
793 #ifndef MACOSX
794
osl_psz_getConfigDir(oslSecurity Security,sal_Char * pszDirectory,sal_uInt32 nMax)795 static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
796 {
797 sal_Char *pStr = getenv("XDG_CONFIG_HOME");
798
799 if ((pStr == NULL) || (strlen(pStr) == 0) ||
800 (access(pStr, 0) != 0))
801 return (osl_psz_getHomeDir(Security, pszDirectory, nMax));
802
803 strncpy(pszDirectory, pStr, nMax);
804 return sal_True;
805 }
806
807 #else
808
809 /*
810 * FIXME: rewrite to use more flexible
811 * NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)
812 * as soon as we can bumb the baseline to Tiger (for NSApplicationSupportDirectory) and have
813 * support for Objective-C in the build environment
814 */
815
816 #define MACOSX_CONFIG_DIR "/Library/Application Support"
osl_psz_getConfigDir(oslSecurity Security,sal_Char * pszDirectory,sal_uInt32 nMax)817 static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
818 {
819 if( osl_psz_getHomeDir(Security, pszDirectory, nMax - sizeof(MACOSX_CONFIG_DIR) + 1) )
820 {
821 strcat( pszDirectory, MACOSX_CONFIG_DIR );
822 return sal_True;
823 }
824
825 return sal_False;
826 }
827
828 #endif
829
osl_isAdministrator(oslSecurity Security)830 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
831 {
832 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
833
834 if (pSecImpl == NULL)
835 return sal_False;
836
837 if (pSecImpl->m_pPasswd.pw_uid != 0)
838 return (sal_False);
839
840 return (sal_True);
841 }
842
osl_freeSecurityHandle(oslSecurity Security)843 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
844 {
845 deleteSecurityImpl(Security);
846 }
847
848
osl_loadUserProfile(oslSecurity Security)849 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
850 {
851 (void) Security; /* unused */
852 return sal_False;
853 }
854
osl_unloadUserProfile(oslSecurity Security)855 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
856 {
857 (void) Security; /* unused */
858 }
859