Changeset 92755 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Dec 6, 2021 9:47:31 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 148666
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
r92750 r92755 92 92 # ifdef RT_OS_DARWIN 93 93 # include <mach-o/dyld.h> 94 # define IPRT_LIBPAM_FILE "libpam.dylib"95 # else96 # define IPRT_LIBPAM_FILE "libpam.so"97 94 # endif 98 95 # include <security/pam_appl.h> … … 142 139 #include "internal/path.h" 143 140 #include "internal/string.h" 141 142 143 /********************************************************************************************************************************* 144 * Defined Constants And Macros * 145 *********************************************************************************************************************************/ 146 #ifdef IPRT_USE_PAM 147 /* 148 * The PAM library names and version ranges to try. 149 */ 150 # ifdef RT_OS_DARWIN 151 # include <mach-o/dyld.h> 152 /** @node libpam.2.dylib was introduced with 10.6.x (OpenPAM); we use 153 * libpam.dylib as that's a symlink to the latest and greatest. */ 154 # define IPRT_LIBPAM_FILE_1 "libpam.dylib" 155 # define IPRT_LIBPAM_FILE_1_FIRST_VER 0 156 # define IPRT_LIBPAM_FILE_1_END_VER 0 157 # define IPRT_LIBPAM_FILE_2 "libpam.2.dylib" 158 # define IPRT_LIBPAM_FILE_2_FIRST_VER 0 159 # define IPRT_LIBPAM_FILE_2_END_VER 0 160 # define IPRT_LIBPAM_FILE_3 "libpam.1.dylib" 161 # define IPRT_LIBPAM_FILE_3_FIRST_VER 0 162 # define IPRT_LIBPAM_FILE_3_END_VER 0 163 # elif RT_OS_LINUX 164 # define IPRT_LIBPAM_FILE_1 "libpam.so.0" 165 # define IPRT_LIBPAM_FILE_1_FIRST_VER 0 166 # define IPRT_LIBPAM_FILE_1_END_VER 0 167 # define IPRT_LIBPAM_FILE_2 "libpam.so" 168 # define IPRT_LIBPAM_FILE_2_FIRST_VER 16 169 # define IPRT_LIBPAM_FILE_2_END_VER 1 170 # else 171 # define IPRT_LIBPAM_FILE_1 "libpam.so" 172 # define IPRT_LIBPAM_FILE_1_MIN_VER 16 173 # define IPRT_LIBPAM_FILE_1_MAX_VER 0 174 # endif 175 #endif 144 176 145 177 … … 246 278 247 279 /* 248 * Use PAM for the authentication. 249 * Note! libpam.2.dylib was introduced with 10.6.x (OpenPAM). 250 */ 251 void *hModPam = dlopen(IPRT_LIBPAM_FILE, RTLD_LAZY | RTLD_GLOBAL); 252 if (hModPam) 253 { 254 int (*pfnPamStart)(const char *, const char *, struct pam_conv *, pam_handle_t **); 255 int (*pfnPamAuthenticate)(pam_handle_t *, int); 256 int (*pfnPamAcctMgmt)(pam_handle_t *, int); 257 int (*pfnPamSetItem)(pam_handle_t *, int, const void *); 258 int (*pfnPamSetCred)(pam_handle_t *, int); 259 char ** (*pfnPamGetEnvList)(pam_handle_t *); 260 int (*pfnPamOpenSession)(pam_handle_t *, int); 261 int (*pfnPamCloseSession)(pam_handle_t *, int); 262 int (*pfnPamEnd)(pam_handle_t *, int); 263 *(void **)&pfnPamStart = dlsym(hModPam, "pam_start"); 264 *(void **)&pfnPamAuthenticate = dlsym(hModPam, "pam_authenticate"); 265 *(void **)&pfnPamAcctMgmt = dlsym(hModPam, "pam_acct_mgmt"); 266 *(void **)&pfnPamSetItem = dlsym(hModPam, "pam_set_item"); 267 *(void **)&pfnPamSetCred = dlsym(hModPam, "pam_setcred"); 268 *(void **)&pfnPamGetEnvList = dlsym(hModPam, "pam_getenvlist"); 269 *(void **)&pfnPamOpenSession = dlsym(hModPam, "pam_open_session"); 270 *(void **)&pfnPamCloseSession = dlsym(hModPam, "pam_close_session"); 271 *(void **)&pfnPamEnd = dlsym(hModPam, "pam_end"); 280 * Dynamically load pam the first time we go thru here. 281 */ 282 static int (*s_pfnPamStart)(const char *, const char *, struct pam_conv *, pam_handle_t **); 283 static int (*s_pfnPamAuthenticate)(pam_handle_t *, int); 284 static int (*s_pfnPamAcctMgmt)(pam_handle_t *, int); 285 static int (*s_pfnPamSetItem)(pam_handle_t *, int, const void *); 286 static int (*s_pfnPamSetCred)(pam_handle_t *, int); 287 static char ** (*s_pfnPamGetEnvList)(pam_handle_t *); 288 static int (*s_pfnPamOpenSession)(pam_handle_t *, int); 289 static int (*s_pfnPamCloseSession)(pam_handle_t *, int); 290 static int (*s_pfnPamEnd)(pam_handle_t *, int); 291 if ( s_pfnPamStart == NULL 292 || s_pfnPamAuthenticate == NULL 293 || s_pfnPamAcctMgmt == NULL 294 || s_pfnPamSetItem == NULL 295 || s_pfnPamEnd == NULL) 296 { 297 RTLDRMOD hModPam = NIL_RTLDRMOD; 298 const char *pszLast; 299 int rc = RTLdrLoadSystemEx(pszLast = IPRT_LIBPAM_FILE_1, RTLDRLOAD_FLAGS_GLOBAL | RTLDRLOAD_FLAGS_NO_UNLOAD 300 | RTLDRLOAD_FLAGS_SO_VER_RANGE(IPRT_LIBPAM_FILE_1_FIRST_VER, IPRT_LIBPAM_FILE_1_END_VER), 301 &hModPam); 302 # ifdef IPRT_LIBPAM_FILE_2 303 if (RT_FAILURE(rc)) 304 rc = RTLdrLoadSystemEx(pszLast = IPRT_LIBPAM_FILE_2, RTLDRLOAD_FLAGS_GLOBAL | RTLDRLOAD_FLAGS_NO_UNLOAD 305 | RTLDRLOAD_FLAGS_SO_VER_RANGE(IPRT_LIBPAM_FILE_2_FIRST_VER, IPRT_LIBPAM_FILE_2_END_VER), 306 &hModPam); 307 # endif 308 # ifdef IPRT_LIBPAM_FILE_3 309 if (RT_FAILURE(rc)) 310 rc = RTLdrLoadSystemEx(pszLast = IPRT_LIBPAM_FILE_3, RTLDRLOAD_FLAGS_GLOBAL | RTLDRLOAD_FLAGS_NO_UNLOAD 311 | RTLDRLOAD_FLAGS_SO_VER_RANGE(IPRT_LIBPAM_FILE_3_FIRST_VER, IPRT_LIBPAM_FILE_3_END_VER), 312 &hModPam); 313 # endif 314 if (RT_FAILURE(rc)) 315 { 316 LogRelMax(10, ("failed to load %s: %Rrc\n", pszLast, rc)); 317 return VERR_AUTHENTICATION_FAILURE; 318 } 319 320 *(PFNRT *)&s_pfnPamStart = RTLdrGetFunction(hModPam, "pam_start"); 321 *(PFNRT *)&s_pfnPamAuthenticate = RTLdrGetFunction(hModPam, "pam_authenticate"); 322 *(PFNRT *)&s_pfnPamAcctMgmt = RTLdrGetFunction(hModPam, "pam_acct_mgmt"); 323 *(PFNRT *)&s_pfnPamSetItem = RTLdrGetFunction(hModPam, "pam_set_item"); 324 *(PFNRT *)&s_pfnPamSetCred = RTLdrGetFunction(hModPam, "pam_setcred"); 325 *(PFNRT *)&s_pfnPamGetEnvList = RTLdrGetFunction(hModPam, "pam_getenvlist"); 326 *(PFNRT *)&s_pfnPamOpenSession = RTLdrGetFunction(hModPam, "pam_open_session"); 327 *(PFNRT *)&s_pfnPamCloseSession = RTLdrGetFunction(hModPam, "pam_close_session"); 328 *(PFNRT *)&s_pfnPamEnd = RTLdrGetFunction(hModPam, "pam_end"); 329 330 RTLdrClose(hModPam); 331 272 332 ASMCompilerBarrier(); 273 if ( pfnPamStart 274 && pfnPamAuthenticate 275 && pfnPamAcctMgmt 276 && pfnPamSetItem 277 && pfnPamEnd) 278 { 279 # define pam_start pfnPamStart 280 # define pam_authenticate pfnPamAuthenticate 281 # define pam_acct_mgmt pfnPamAcctMgmt 282 # define pam_set_item pfnPamSetItem 283 # define pam_setcred pfnPamSetCred 284 # define pam_getenvlist pfnPamGetEnvList 285 # define pam_open_session pfnPamOpenSession 286 # define pam_close_session pfnPamCloseSession 287 # define pam_end pfnPamEnd 288 289 /* Do the PAM stuff. */ 290 pam_handle_t *hPam = NULL; 291 RTPROCPAMARGS PamConvArgs = { pszUser, pszPassword }; 292 struct pam_conv PamConversation; 293 RT_ZERO(PamConversation); 294 PamConversation.appdata_ptr = &PamConvArgs; 295 PamConversation.conv = rtPamConv; 296 int rc = pam_start(pszPamService, pszUser, &PamConversation, &hPam); 333 if ( s_pfnPamStart == NULL 334 || s_pfnPamAuthenticate == NULL 335 || s_pfnPamAcctMgmt == NULL 336 || s_pfnPamSetItem == NULL 337 || s_pfnPamEnd == NULL) 338 { 339 LogRelMax(10, ("failed to resolve symbols: %p %p %p %p %p\n", 340 s_pfnPamStart, s_pfnPamAuthenticate, s_pfnPamAcctMgmt, s_pfnPamSetItem, s_pfnPamEnd)); 341 return VERR_AUTHENTICATION_FAILURE; 342 } 343 } 344 345 # define pam_start s_pfnPamStart 346 # define pam_authenticate s_pfnPamAuthenticate 347 # define pam_acct_mgmt s_pfnPamAcctMgmt 348 # define pam_set_item s_pfnPamSetItem 349 # define pam_setcred s_pfnPamSetCred 350 # define pam_getenvlist s_pfnPamGetEnvList 351 # define pam_open_session s_pfnPamOpenSession 352 # define pam_close_session s_pfnPamCloseSession 353 # define pam_end s_pfnPamEnd 354 355 /* 356 * Do the PAM stuff. 357 */ 358 pam_handle_t *hPam = NULL; 359 RTPROCPAMARGS PamConvArgs = { pszUser, pszPassword }; 360 struct pam_conv PamConversation; 361 RT_ZERO(PamConversation); 362 PamConversation.appdata_ptr = &PamConvArgs; 363 PamConversation.conv = rtPamConv; 364 int rc = pam_start(pszPamService, pszUser, &PamConversation, &hPam); 365 if (rc == PAM_SUCCESS) 366 { 367 rc = pam_set_item(hPam, PAM_RUSER, pszUser); 368 if (rc == PAM_SUCCESS) 369 { 370 if (pfMayFallBack) 371 *pfMayFallBack = false; 372 rc = pam_authenticate(hPam, 0); 297 373 if (rc == PAM_SUCCESS) 298 374 { 299 rc = pam_set_item(hPam, PAM_RUSER, pszUser); 300 if (rc == PAM_SUCCESS) 375 rc = pam_acct_mgmt(hPam, 0); 376 if ( rc == PAM_SUCCESS 377 || rc == PAM_AUTHINFO_UNAVAIL /*??*/) 301 378 { 302 if (pfMayFallBack) 303 *pfMayFallBack = false; 304 rc = pam_authenticate(hPam, 0); 305 if (rc == PAM_SUCCESS) 379 if ( ppapszEnv 380 && s_pfnPamGetEnvList 381 && s_pfnPamSetCred) 306 382 { 307 rc = pam_acct_mgmt(hPam, 0); 308 if ( rc == PAM_SUCCESS 309 || rc == PAM_AUTHINFO_UNAVAIL /*??*/) 310 { 311 if ( ppapszEnv 312 && pfnPamGetEnvList 313 && pfnPamSetCred) 314 { 315 /* pam_env.so creates the environment when pam_setcred is called. */ 316 rc = pam_setcred(hPam, PAM_ESTABLISH_CRED | PAM_SILENT); 317 /** @todo check pam_setcred status code. */ 318 *ppapszEnv = pam_getenvlist(hPam); 319 pam_setcred(hPam, PAM_DELETE_CRED); 320 } 321 322 pam_end(hPam, PAM_SUCCESS); 323 dlclose(hModPam); 324 return VINF_SUCCESS; 325 } 326 LogFunc(("pam_acct_mgmt -> %d\n", rc)); 383 /* pam_env.so creates the environment when pam_setcred is called,. */ 384 int rcSetCred = pam_setcred(hPam, PAM_ESTABLISH_CRED | PAM_SILENT); 385 /** @todo check pam_setcred status code? */ 386 387 /* Unless it does it during session opening (Ubuntu 21.10). This 388 unfortunately means we might mount user dir and other crap: */ 389 /** @todo do session handling properly */ 390 int rcOpenSession = PAM_ABORT; 391 if ( s_pfnPamOpenSession 392 && s_pfnPamCloseSession) 393 rcOpenSession = pam_open_session(hPam, PAM_SILENT); 394 395 *ppapszEnv = pam_getenvlist(hPam); 396 LogFlowFunc(("pam_getenvlist -> %p ([0]=%p); rcSetCred=%d rcOpenSession=%d\n", 397 *ppapszEnv, *ppapszEnv ? **ppapszEnv : NULL, rcSetCred, rcOpenSession)); RT_NOREF(rcSetCred); 398 399 if (rcOpenSession == PAM_SUCCESS) 400 pam_close_session(hPam, PAM_SILENT); 401 pam_setcred(hPam, PAM_DELETE_CRED); 327 402 } 328 else 329 LogFunc(("pam_authenticate -> %d\n", rc)); 403 404 pam_end(hPam, PAM_SUCCESS); 405 LogFlowFunc(("pam auth (for %s) successful\n", pszPamService)); 406 return VINF_SUCCESS; 330 407 } 331 else 332 LogFunc(("pam_set_item/PAM_RUSER -> %d\n", rc)); 333 pam_end(hPam, rc); 408 LogFunc(("pam_acct_mgmt -> %d\n", rc)); 334 409 } 335 410 else 336 LogFunc(("pam_ start-> %d\n", rc));411 LogFunc(("pam_authenticate -> %d\n", rc)); 337 412 } 338 413 else 339 LogFunc(("failed to resolve symbols: %p %p %p %p %p\n", 340 pfnPamStart, pfnPamAuthenticate, pfnPamAcctMgmt, pfnPamSetItem, pfnPamEnd)); 341 dlclose(hModPam); 414 LogFunc(("pam_set_item/PAM_RUSER -> %d\n", rc)); 415 pam_end(hPam, rc); 342 416 } 343 417 else 344 LogFunc((" Loading " IPRT_LIBPAM_FILE " failed\n"));418 LogFunc(("pam_start(%s) -> %d\n", pszPamService, rc)); 345 419 return VERR_AUTHENTICATION_FAILURE; 346 420 } … … 1376 1450 } 1377 1451 else 1378 pszEncoding = " C";1452 pszEncoding = "ASCII"; 1379 1453 } 1380 1454
Note:
See TracChangeset
for help on using the changeset viewer.