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 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 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 111 static void deleteSecurityImpl(oslSecurityImpl * impl) { 112 free(impl); 113 } 114 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 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 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 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 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 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 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 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 */ 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=NULL; 453 rtl_String* strPassword=NULL; 454 sal_Char* pszUserName=NULL; 455 sal_Char* pszPassword=NULL; 456 457 if ( ustrUserName != NULL ) 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 != NULL ) 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 != NULL ) 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 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 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 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 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 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 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 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 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 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 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" 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 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 843 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security) 844 { 845 deleteSecurityImpl(Security); 846 } 847 848 849 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security) 850 { 851 (void) Security; /* unused */ 852 return sal_False; 853 } 854 855 void SAL_CALL osl_unloadUserProfile(oslSecurity Security) 856 { 857 (void) Security; /* unused */ 858 } 859