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