Changeset 75725 in vbox
- Timestamp:
- Nov 25, 2018 7:18:32 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
r69111 r75725 64 64 #ifdef RT_OS_DARWIN 65 65 # include <mach-o/dyld.h> 66 #endif 66 # include <security/pam_appl.h> 67 # include <stdlib.h> 68 # include <dlfcn.h> 69 # include <iprt/asm.h> 70 #endif 71 67 72 #ifdef RT_OS_SOLARIS 68 73 # include <limits.h> … … 88 93 #include <iprt/err.h> 89 94 #include <iprt/file.h> 95 #include <iprt/log.h> 90 96 #include <iprt/path.h> 91 97 #include <iprt/pipe.h> … … 94 100 #include <iprt/mem.h> 95 101 #include "internal/process.h" 102 103 104 /********************************************************************************************************************************* 105 * Structures and Typedefs * 106 *********************************************************************************************************************************/ 107 #ifdef RT_OS_DARWIN 108 /** For passing info between rtCheckCredentials and rtPamConv. */ 109 typedef struct RTPROCPAMARGS 110 { 111 const char *pszUser; 112 const char *pszPassword; 113 } RTPROCPAMARGS; 114 /** Pointer to rtPamConv argument package. */ 115 typedef RTPROCPAMARGS *PRTPROCPAMARGS; 116 #endif 117 118 119 #ifdef RT_OS_DARWIN 120 /** 121 * Worker for rtCheckCredentials that feeds password and maybe username to PAM. 122 * 123 * @returns PAM status. 124 * @param cMessages Number of messages. 125 * @param papMessages Message vector. 126 * @param ppaResponses Where to put our responses. 127 * @param pvAppData Pointer to RTPROCPAMARGS. 128 */ 129 static int rtPamConv(int cMessages, const struct pam_message **papMessages, struct pam_response **ppaResponses, void *pvAppData) 130 { 131 LogFlow(("rtPamConv: cMessages=%d\n", cMessages)); 132 PRTPROCPAMARGS pArgs = (PRTPROCPAMARGS)pvAppData; 133 AssertPtrReturn(pArgs, PAM_CONV_ERR); 134 135 struct pam_response *paResponses = (struct pam_response *)calloc(cMessages, sizeof(paResponses[0])); 136 AssertReturn(paResponses, PAM_CONV_ERR); 137 for (int i = 0; i < cMessages; i++) 138 { 139 LogFlow(("rtPamConv: #%d: msg_style=%d msg=%s\n", i, papMessages[i]->msg_style, papMessages[i]->msg)); 140 141 paResponses[i].resp_retcode = 0; 142 if (papMessages[i]->msg_style == PAM_PROMPT_ECHO_OFF) 143 paResponses[i].resp = strdup(pArgs->pszPassword); 144 else if (papMessages[i]->msg_style == PAM_PROMPT_ECHO_ON) 145 paResponses[i].resp = strdup(pArgs->pszUser); 146 else 147 { 148 paResponses[i].resp = NULL; 149 continue; 150 } 151 if (paResponses[i].resp == NULL) 152 { 153 while (i-- > 0) 154 free(paResponses[i].resp); 155 free(paResponses); 156 LogFlow(("rtPamConv: out of memory\n")); 157 return PAM_CONV_ERR; 158 } 159 } 160 161 *ppaResponses = paResponses; 162 return PAM_SUCCESS; 163 } 164 #endif /* RT_OS_DARWIN */ 96 165 97 166 … … 107 176 static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) 108 177 { 109 #if defined(RT_OS_LINUX) 178 #if defined(RT_OS_DARWIN) 179 RTLogPrintf("rtCheckCredentials\n"); 180 181 /* 182 * Resolve user to UID and GID. 183 */ 184 char szBuf[_4K]; 185 struct passwd Pw; 186 struct passwd *pPw; 187 if (getpwnam_r(pszUser, &Pw, szBuf, sizeof(szBuf), &pPw) != 0) 188 return VERR_AUTHENTICATION_FAILURE; 189 if (!pPw) 190 return VERR_AUTHENTICATION_FAILURE; 191 192 *pUid = pPw->pw_uid; 193 *pGid = pPw->pw_gid; 194 195 /* 196 * Use PAM for the authentication. 197 * Note! libpam.2.dylib was introduced with 10.6.x (OpenPAM). 198 */ 199 void *hModPam = dlopen("libpam.dylib", RTLD_LAZY | RTLD_GLOBAL); 200 if (hModPam) 201 { 202 int (*pfnPamStart)(const char *, const char *, struct pam_conv *, pam_handle_t **); 203 int (*pfnPamAuthenticate)(pam_handle_t *, int); 204 int (*pfnPamAcctMgmt)(pam_handle_t *, int); 205 int (*pfnPamSetItem)(pam_handle_t *, int, const void *); 206 int (*pfnPamEnd)(pam_handle_t *, int); 207 *(void **)&pfnPamStart = dlsym(hModPam, "pam_start"); 208 *(void **)&pfnPamAuthenticate = dlsym(hModPam, "pam_authenticate"); 209 *(void **)&pfnPamAcctMgmt = dlsym(hModPam, "pam_acct_mgmt"); 210 *(void **)&pfnPamSetItem = dlsym(hModPam, "pam_set_item"); 211 *(void **)&pfnPamEnd = dlsym(hModPam, "pam_end"); 212 ASMCompilerBarrier(); 213 if ( pfnPamStart 214 && pfnPamAuthenticate 215 && pfnPamAcctMgmt 216 && pfnPamSetItem 217 && pfnPamEnd) 218 { 219 #define pam_start pfnPamStart 220 #define pam_authenticate pfnPamAuthenticate 221 #define pam_acct_mgmt pfnPamAcctMgmt 222 #define pam_set_item pfnPamSetItem 223 #define pam_end pfnPamEnd 224 225 /* Do the PAM stuff. 226 Note! Abusing 'login' here for now... */ 227 pam_handle_t *hPam = NULL; 228 RTPROCPAMARGS PamConvArgs = { pszUser, pszPasswd }; 229 struct pam_conv PamConversation; 230 RT_ZERO(PamConversation); 231 PamConversation.appdata_ptr = &PamConvArgs; 232 PamConversation.conv = rtPamConv; 233 int rc = pam_start("login", pszUser, &PamConversation, &hPam); 234 if (rc == PAM_SUCCESS) 235 { 236 rc = pam_set_item(hPam, PAM_RUSER, pszUser); 237 if (rc == PAM_SUCCESS) 238 rc = pam_authenticate(hPam, 0); 239 if (rc == PAM_SUCCESS) 240 { 241 rc = pam_acct_mgmt(hPam, 0); 242 if ( rc == PAM_SUCCESS 243 || rc == PAM_AUTHINFO_UNAVAIL /*??*/) 244 { 245 pam_end(hPam, PAM_SUCCESS); 246 dlclose(hModPam); 247 return VINF_SUCCESS; 248 } 249 Log(("rtCheckCredentials: pam_acct_mgmt -> %d\n", rc)); 250 } 251 else 252 Log(("rtCheckCredentials: pam_authenticate -> %d\n", rc)); 253 pam_end(hPam, rc); 254 } 255 else 256 Log(("rtCheckCredentials: pam_start -> %d\n", rc)); 257 } 258 else 259 Log(("rtCheckCredentials: failed to resolve symbols: %p %p %p %p %p\n", 260 pfnPamStart, pfnPamAuthenticate, pfnPamAcctMgmt, pfnPamSetItem, pfnPamEnd)); 261 dlclose(hModPam); 262 } 263 else 264 Log(("rtCheckCredentials: Loading libpam.dylib failed\n")); 265 return VERR_AUTHENTICATION_FAILURE; 266 267 #elif defined(RT_OS_LINUX) 110 268 struct passwd *pw; 111 269 … … 172 330 } 173 331 174 175 332 #ifdef RT_OS_SOLARIS 333 176 334 /** @todo the error reporting of the Solaris process contract code could be 177 335 * a lot better, but essentially it is not meant to run into errors after … … 451 609 { 452 610 int rc; 611 LogFlow(("RTProcCreateEx: pszExec=%s pszAsUser=%s\n", pszExec, pszAsUser)); 453 612 454 613 /*
Note:
See TracChangeset
for help on using the changeset viewer.

