"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "brutus-server/servant_impl/BrutusLogOnS_impl.cpp" of archive brutus-server-1.0.0.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * Brutus source file for the BrutusLogOn servant.
3 * Copyright (C) 2004 OMC Denmark ApS.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <brutus-server/servant_impl/BrutusLogOnS_impl.h>
21 #include <brutus-server/servant_impl/IMAPISessionS_impl.h>
22 #include <tao/PortableServer/ServantActivatorC.h>
23 #include <ace/string_base.h>
24
25 #include <brutus-server/defines.h>
26 #include <brutus-server/config.h>
27 #include <brutus-server/macros.h>
28 #include <brutus-server/rsa_utils.h>
29 #include <Windows.h>
30 #include <brutus-server/edkinc/edkmdb.h>
31
32 #define MAPIGUID_H // do not include mapiguid.h
33 #include <mapiutil.h>
34
35 // MAPI_ALLOW_OTHERS is ignored due to security concerns
36 // MAPI_NEW_SESSION is forced due to security concerns
37 // All UI related flags are ignored
38 // MAPI_FORCE_DOWNLOAD is ignored. Unclear how it should be interpreted
39 static inline FLAGS native_logon_flags(const ::BRUTUS::BDEFINE Flags)
40 {
41 ::BRUTUS::BDEFINE flags = Flags;
42 FLAGS retval = 0;
43
44 retval |= MAPI_EXTENDED;
45 retval |= MAPI_NT_SERVICE;
46 retval |= MAPI_NEW_SESSION;
47
48 if (flags & ::BRUTUS::BRUTUS_UNIQUE_SESSION) // ignore this flag here
49 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_UNIQUE_SESSION);
50
51 if (flags & ::BRUTUS::BRUTUS_MAPI_NO_MAIL) {
52 retval |= MAPI_NO_MAIL;
53 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_NO_MAIL);
54 }
55 if (flags & ::BRUTUS::BRUTUS_MAPI_DEFAULT_SERVICES) {
56 retval |= MAPI_DEFAULT_SERVICES;
57 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_DEFAULT_SERVICES);
58 }
59 if (flags & ::BRUTUS::BRUTUS_MAPI_TIMEOUT_SHORT) {
60 retval |= MAPI_TIMEOUT_SHORT;
61 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_TIMEOUT_SHORT);
62 }
63 if (flags & ::BRUTUS::BRUTUS_MAPI_USE_DEFAULT) {
64 retval |= MAPI_USE_DEFAULT;
65 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_USE_DEFAULT);
66 }
67 if (flags & ::BRUTUS::BRUTUS_MAPI_EXPLICIT_PROFILE) {
68 retval |= MAPI_EXPLICIT_PROFILE;
69 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_EXPLICIT_PROFILE);
70 }
71 if (flags & ::BRUTUS::BRUTUS_MAPI_BG_SESSION) {
72 retval |= MAPI_BG_SESSION;
73 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_BG_SESSION);
74 }
75
76 // Must(?) fix handling of Unicode characters
77 if (flags & ::BRUTUS::BRUTUS_MAPI_UNICODE) {
78 retval |= MAPI_UNICODE;
79 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_UNICODE);
80 }
81
82 if (flags) {
83 char msg[128] = {0};
84 sprintf_s(msg, sizeof(msg), "Unknown or unsupported flag(s) from BRUTUS : %X", flags);
85 BRUTUS_LOG_BUG(msg);
86 }
87
88 return retval;
89 }
90
91 static inline FLAGS native_create_profile_flags(const ::BRUTUS::BDEFINE Flags)
92 {
93 ::BRUTUS::BDEFINE flags = Flags;
94 FLAGS retval = 0;
95
96 if (flags & ::BRUTUS::BRUTUS_MAPI_DEFAULT_SERVICES) {
97 retval |= MAPI_DEFAULT_SERVICES;
98 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_DEFAULT_SERVICES);
99 }
100
101 // Must(?) fix handling of Unicode characters
102 if (flags & ::BRUTUS::BRUTUS_MAPI_UNICODE) {
103 retval |= MAPI_UNICODE;
104 FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_UNICODE);
105 }
106
107 if (flags) {
108 char msg[128] = {0};
109 sprintf_s(msg, sizeof(msg), "Unknown or unsupported flag(s) from BRUTUS : %X", flags);
110 BRUTUS_LOG_BUG(msg);
111 }
112
113 return retval;
114 }
115
116 static inline const char *spawn_status_msg(const ::BRUTUS::ProxyManager::SpawnStatus spawn_status)
117 {
118 switch (spawn_status) {
119 case ::BRUTUS::ProxyManager::spawn_error_authentication :
120 return "Spawn failure: spawn_error_authentication";
121 break;
122 case ::BRUTUS::ProxyManager::spawn_error_mapi_logon :
123 return "Spawn failure: spawn_error_mapi_logon";
124 break;
125 case ::BRUTUS::ProxyManager::spawn_error_mapi_no_profile :
126 return "Spawn failure: spawn_error_mapi_no_profile";
127 break;
128 case ::BRUTUS::ProxyManager::spawn_error_lifeline :
129 return "Spawn failure: spawn_error_lifeline";
130 break;
131 case ::BRUTUS::ProxyManager::spawn_error_exception :
132 return "Spawn failure: spawn_error_exception";
133 break;
134 case ::BRUTUS::ProxyManager::spawn_error_impersonation :
135 return "Spawn failure: spawn_error_impersonation";
136 break;
137 case ::BRUTUS::ProxyManager::spawn_error_config :
138 return "Spawn failure: spawn_error_config";
139 break;
140 case ::BRUTUS::ProxyManager::spawn_error_corba :
141 return "Spawn failure: spawn_error_corba";
142 break;
143 case ::BRUTUS::ProxyManager::spawn_error_mapi_init :
144 return "Spawn failure: spawn_error_mapi_init";
145 break;
146 case ::BRUTUS::ProxyManager::spawn_error_spawn :
147 return "Spawn failure: spawn_error_spawn";
148 break;
149 case ::BRUTUS::ProxyManager::spawn_duplicate :
150 return "Spawn failure: spawn_duplicate";
151 break;
152 case ::BRUTUS::ProxyManager::spawn_ok :
153 return "Spawn OK";
154 break;
155 default :
156 return "Unknown Spawn failure";
157 break;
158 }
159 }
160
161 static inline bool authenticate_user(const char *WindowsUserName,
162 const char *WindowsDomainName,
163 const char *WindowsUserPassword)
164 {
165 BRUTUS_LOG_REF;
166 HANDLE credentials = NULL;
167
168 if (LogonUser((char*)WindowsUserName,
169 (char*)WindowsDomainName,
170 (char*)WindowsUserPassword,
171 LOGON32_LOGON_NETWORK,
172 LOGON32_PROVIDER_DEFAULT,
173 &credentials)) {
174 CloseHandle(credentials);
175 return true;
176 }
177 if (credentials)
178 CloseHandle(credentials);
179
180 DWORD err = GetLastError();
181 char msg[512] = {0};
182 LPVOID msg_buf;
183
184 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
185 NULL,
186 err,
187 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
188 (LPTSTR) &msg_buf,
189 0,
190 NULL );
191 ((char*)msg_buf)[strlen((char*)msg_buf) - 2] = '\0';
192
193 _snprintf_s(msg, sizeof(msg), sizeof(msg), "LogonUser(%s\\%s) failed - GetLastError() returned: 0x%X (%s)", WindowsDomainName, WindowsUserName, err, (const char*)msg_buf);
194 LocalFree(msg_buf);
195 BRUTUS_LOG_SUB_PRIVATE(msg);
196
197 return false;
198 }
199
200 BRUTUS_BrutusLogOn_i::BRUTUS_BrutusLogOn_i(::PortableServer::POA_ptr Poa,
201 ::SessionRegistry *Registry,
202 const bool ProcessPerSession,
203 const bool OnlyAdministrator,
204 const bool Authenticate,
205 const bool ProfilesOnDisk,
206 const unsigned long CheckLifeDelay,
207 ::CORBA::ORB_ptr ORB)
208 : poa_(::PortableServer::POA::_duplicate(Poa)),
209 served_sessions_(Registry),
210 process_per_session_(ProcessPerSession),
211 only_administrator_(OnlyAdministrator),
212 authenticate_(Authenticate),
213 profiles_on_disk_(ProfilesOnDisk),
214 exchange_2007_(false),
215 check_life_delay_(CheckLifeDelay)
216 {
217 Config *conf = new Config();
218
219 // load configuration
220 if (conf->load(BRUTUS_CONF)) {
221 delete conf;
222 throw 0;
223 }
224
225 // MAPI options
226 char *exchange_version_str = NULL;
227 exchange_version_str = conf->get_value("EXCHANGE_SERVER_VERSION");
228 if ((exchange_version_str) && (!strcmp(exchange_version_str, "2007")))
229 exchange_2007_ = true;
230 free(exchange_version_str);
231 delete conf;
232
233 internal_orb_ = ::CORBA::ORB::_duplicate(ORB);
234 proxy_manager_ = ::BRUTUS::ProxyManager::_nil();
235 if (process_per_session_) {
236 try {
237 ::CORBA::Object_var object = internal_orb_->string_to_object(PROXY_MANAGER_IOR);
238 proxy_manager_ = ::BRUTUS::ProxyManager::_narrow(object.in());
239 }
240 catch (...) {
241 }
242 }
243 }
244
245 void BRUTUS_BrutusLogOn_i::GetVersion(::BRUTUS::BrutusLogOn::BrutusVersion_out version)
246 {
247 BRUTUS_LOG_REF;
248 BRUTUS_LOG_SUB_INF("Entering BRUTUS_BrutusLogOn_i::GetVersion()");
249
250 ::BRUTUS::BrutusLogOn::BrutusVersion_var ver;
251
252 try {
253 ver = new ::BRUTUS::BrutusLogOn::BrutusVersion;
254 }
255 catch (std::bad_alloc &) {
256 BRUTUS_LOG_SUB_ERR("No memory");
257 throw ::CORBA::NO_MEMORY();
258 }
259 ver->major = (::CORBA::UShort)BRUTUS_VERSION_MAJOR;
260 ver->minor = (::CORBA::UShort)BRUTUS_VERSION_MINOR;
261 ver->micro = (::CORBA::UShort)BRUTUS_VERSION_MICRO;
262 ver->release_tag = (::CORBA::UShort)BRUTUS_VERSION_RELEASE_TAG;
263
264 version = ver._retn();
265
266 BRUTUS_LOG_SUB_INF("Leaving BRUTUS_BrutusLogOn_i::GetVersion()");
267 }
268
269 void BRUTUS_BrutusLogOn_i::GetPublicKey(::BRUTUS::seq_octet_out PubKey)
270 {
271 BRUTUS_LOG_REF;
272 BRUTUS_LOG_SUB_INF("Entering BRUTUS_BrutusLogOn_i::GetPublicKey()");
273
274 char *key = NULL;
275 int len = 0;
276 struct _stat pk_stat = { 0 };
277
278 ::BRUTUS::seq_octet_var pubkey;
279 try {
280 pubkey = new ::BRUTUS::seq_octet;
281 }
282 catch (std::bad_alloc &) {
283 BRUTUS_LOG_SUB_ERR("No memory");
284 throw ::CORBA::NO_MEMORY();
285 }
286 pubkey->length(0);
287
288 // get size of public key
289 if (_stat(PUBLIC_KEY, &pk_stat)) {
290 BRUTUS_LOG_SUB_ERR("Could not stat public key file");
291 goto exit;
292 }
293 key = (char*)malloc(pk_stat.st_size);
294 if (!key) {
295 BRUTUS_LOG_SUB_ERR("No memory");
296 throw ::CORBA::NO_MEMORY();
297 }
298
299 FILE *file = NULL;
300 if (fopen_s(&file, PUBLIC_KEY, "r")) {
301 BRUTUS_LOG_SUB_ERR("Could not open public key file");
302 goto exit;
303 }
304
305 len = fscanf_s(file, "%as", &key, pk_stat.st_size);
306 if (file) // C6387
307 fclose(file);
308 if (!len)
309 BRUTUS_LOG_SUB_ERR("Could not read public key");
310 else {
311 unsigned long n = 0;
312 pubkey->length(len);
313 do {
314 pubkey[n] = (::CORBA::Octet)key[n];
315 n++;
316 } while(--len);
317 }
318
319 exit:
320 free(key);
321 PubKey = pubkey._retn();
322
323 BRUTUS_LOG_SUB_INF("Leaving BRUTUS_BrutusLogOn_i::GetPublicKey()");
324 }
325
326 ::BRUTUS::BRESULT BRUTUS_BrutusLogOn_i::Logon(::BRUTUS::BrutusCheck_ptr LifeLine,
327 const char *MAPIProfileName,
328 const char *MAPIProfilePassword,
329 const char *WindowsUserName,
330 const char *WindowsDomainName,
331 const char *WindowsUserPassword,
332 const char *MailboxName,
333 const char *ServerName,
334 ::BRUTUS::BDEFINE LogonFlags,
335 ::BRUTUS::BDEFINE ProfileFlags,
336 ::BRUTUS::SERVER_TYPE ServerType,
337 ::CORBA::ULong_out InstanceID,
338 ::BRUTUS::IMAPISession_out Session)
339 {
340 BRUTUS_LOG_REF;
341 Session = ::BRUTUS::IMAPISession::_nil();
342
343 if (::CORBA::is_nil(LifeLine)) {
344 BRUTUS_LOG_SUB_BUG("LifeLine parameter was NIL");
345 return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
346 }
347
348 try {
349 ::CORBA::String_var life_line_ior = internal_orb_->object_to_string(LifeLine);
350 if (NULL == life_line_ior.in()) {
351 BRUTUS_LOG_SUB_BUG("IOR is NULL");
352 return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
353 }
354 BRUTUS_LOG_SUB_INF("Validating LifeLine object reference");
355 BRUTUS_LOG_SUB_INF(life_line_ior.in());
356 LifeLine->ping();
357 }
358 catch (const ::CORBA::TIMEOUT &) {
359 BRUTUS_LOG_SUB_BUG("Timeout trying to validate lifeline");
360 return ::BRUTUS::BRUTUS_LIFELINE_TIMEOUT;
361 }
362 catch (const ::CORBA::Exception &e) {
363 BRUTUS_LOG_SUB_BUG(e._info().c_str());
364 return ::BRUTUS::BRUTUS_EXCEPTION_FROM_CLIENT;
365 }
366 catch (...) {
367 BRUTUS_LOG_SUB_BUG("Unknown exception caught");
368 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
369 }
370
371 return create_session(check_life_delay_,
372 LifeLine,
373 MAPIProfileName,
374 MAPIProfilePassword,
375 WindowsUserName,
376 (const char*)(strlen(WindowsDomainName) ? WindowsDomainName : NULL), // take care of UPN authentication
377 WindowsUserPassword,
378 MailboxName,
379 ServerName,
380 LogonFlags,
381 ProfileFlags,
382 ServerType,
383 InstanceID,
384 Session);
385 }
386
387 ::BRUTUS::BRESULT BRUTUS_BrutusLogOn_i::create_session(const unsigned long CheckLifeDelay,
388 ::BRUTUS::BrutusCheck_ptr LifeLine,
389 const char *MAPIProfileName,
390 const char *MAPIProfilePassword,
391 const char *WindowsUserName,
392 const char *WindowsDomainName,
393 const char *WindowsUserPassword,
394 const char *MailboxName,
395 const char *ServerName,
396 ::BRUTUS::BDEFINE LogonFlags,
397 ::BRUTUS::BDEFINE ProfileFlags,
398 ::BRUTUS::SERVER_TYPE ServerType,
399 ::CORBA::ULong_out InstanceID,
400 ::BRUTUS::IMAPISession_out Session)
401 {
402 BRUTUS_LOG_REF;
403 BRUTUS_LOG_SUB_INF("Entering BRUTUS_BrutusLogOn_i::Logon()");
404
405 bool null_profile_passwd = false;
406 bool retry = true;
407 ::BRUTUS::IMAPISession_var session = ::BRUTUS::IMAPISession::_nil();
408 ::BRUTUS::BRESULT br = ::BRUTUS::BRUTUS_INTERNAL_ERROR;
409 const char *user = only_administrator_ ? "Administrator" : WindowsUserName;
410
411 InstanceID = 0;
412 Session = ::BRUTUS::IMAPISession::_nil();
413
414 if (authenticate_) {
415 if (!authenticate_user(user, WindowsDomainName, WindowsUserPassword))
416 return ::BRUTUS::BRUTUS_MAPI_E_LOGON_FAILED;
417 else {
418 char msg[512] = {0};
419 sprintf_s(msg, sizeof(msg), "%s\\%s authenticated sucessfully - proceeding with logon", WindowsDomainName, user);
420 BRUTUS_LOG_SUB_PRIVATE(msg);
421 }
422 }
423 if (!MAPIProfileName || !strlen(MAPIProfileName))
424 return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
425 else if (strlen(MAPIProfileName) > 64)
426 return ::BRUTUS::BRUTUS_MAPI_E_STRING_TOO_LONG;
427 if (MAPIProfilePassword && (strlen(MAPIProfilePassword) > 64))
428 return ::BRUTUS::BRUTUS_MAPI_E_STRING_TOO_LONG;
429 if (!strlen(MAPIProfilePassword))
430 null_profile_passwd = true;
431
432 BRUTUS_LOG_SUB_PRIVATE(MAPIProfileName);
433
434 if (process_per_session_) {
435 ::CORBA::Object_var object = ::CORBA::Object::_nil();
436 const char *server_type = NULL;
437
438 switch (ServerType) {
439 case ::BRUTUS::SERVER_TYPE_EXCHANGE:
440 server_type = "MSEMS";
441 break;
442 case ::BRUTUS::SERVER_TYPE_DOMINO:
443 server_type = "NOTES";
444 break;
445 default:
446 BRUTUS_LOG_SUB_BUG("Message service not supported");
447 return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
448 }
449
450 if (::CORBA::is_nil(proxy_manager_.in())) {
451 try {
452 object = internal_orb_->string_to_object(PROXY_MANAGER_IOR);
453 proxy_manager_ = ::BRUTUS::ProxyManager::_narrow(object.in());
454 }
455 catch (...) {
456 }
457 }
458 if (::CORBA::is_nil(proxy_manager_.in())) {
459 BRUTUS_LOG_SUB_CRITICAL("Could not get Proxy Manager reference");
460 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
461 }
462
463 try {
464 ::CORBA::String_var life_line_ior = internal_orb_->object_to_string(LifeLine);
465 if (NULL == life_line_ior.in()) {
466 BRUTUS_LOG_SUB_BUG("IOR is NULL");
467 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
468 }
469
470 if (!proxy_manager_->setUser(life_line_ior.in(),
471 user,
472 WindowsDomainName,
473 WindowsUserPassword,
474 MAPIProfileName,
475 MAPIProfilePassword,
476 MailboxName,
477 ServerName,
478 server_type,
479 LogonFlags,
480 ProfileFlags)) {
481 char msg[512] = {0};
482 sprintf_s(msg, sizeof(msg), "Could not spawn proxy process for %s/%s. Impersonation failed, check user privileges.", user, WindowsDomainName);
483 ACE_DEBUG((LM_CRITICAL, ACE_TEXT(msg)));
484 BRUTUS_LOG_SUB_CRITICAL(msg);
485 return ::BRUTUS::BRUTUS_MAPI_E_LOGON_FAILED;
486 }
487 }
488 catch (...) {
489 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
490 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
491 }
492
493 ::CORBA::String_var session_ior = (const char*)"";
494 ::BRUTUS::ProxyManager::SpawnStatus spawn_status;
495 try { // this call takes the longest time in the logon process
496 spawn_status = proxy_manager_->getSession(MAPIProfileName,
497 session_ior.out());
498 }
499 catch (const ::CORBA::Exception &e) {
500 BRUTUS_LOG_SUB_CRITICAL(e._info().c_str());
501 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
502 }
503 catch (...) {
504 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
505 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
506 }
507 if ((spawn_status == ::BRUTUS::ProxyManager::spawn_ok) || (spawn_status == ::BRUTUS::ProxyManager::spawn_duplicate)) {
508 try {
509 object = internal_orb_->string_to_object(session_ior.in());
510 session = ::BRUTUS::IMAPISession::_narrow(object.in());
511 }
512 catch (...) {
513 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
514 }
515 if (::CORBA::is_nil(object.in()))
516 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
517 } else {
518 switch (spawn_status) {
519 case ::BRUTUS::ProxyManager::spawn_error_authentication :
520 case ::BRUTUS::ProxyManager::spawn_error_mapi_logon :
521 br = ::BRUTUS::BRUTUS_MAPI_E_LOGON_FAILED;
522 break;
523 case ::BRUTUS::ProxyManager::spawn_error_mapi_no_profile :
524 br = ::BRUTUS::BRUTUS_MAPI_E_NOT_FOUND;
525 break;
526 case ::BRUTUS::ProxyManager::spawn_error_lifeline :
527 br = ::BRUTUS::BRUTUS_LIFELINE_ERROR;
528 break;
529 case ::BRUTUS::ProxyManager::spawn_error_exception :
530 case ::BRUTUS::ProxyManager::spawn_error_impersonation :
531 case ::BRUTUS::ProxyManager::spawn_error_config :
532 case ::BRUTUS::ProxyManager::spawn_error_corba :
533 case ::BRUTUS::ProxyManager::spawn_error_mapi_init :
534 case ::BRUTUS::ProxyManager::spawn_error_spawn :
535 default :
536 br = ::BRUTUS::BRUTUS_INTERNAL_ERROR;
537 }
538 BRUTUS_LOG_SUB_CRITICAL(spawn_status_msg(spawn_status));
539 return br;
540 }
541
542 // the user is already authenticated
543 if (spawn_status == ::BRUTUS::ProxyManager::spawn_duplicate) {
544 BRUTUS_LOG_SUB_INF("Duplicate session created");
545 InstanceID = session->addLifeline(LifeLine);
546 } else {
547 BRUTUS_LOG_SUB_INF("New session created");
548 InstanceID = 0;
549 }
550
551 br = ::BRUTUS::BRUTUS_S_OK;
552 Session = session._retn();
553 } else {
554 LPMAPISESSION mapi_session = NULL;
555 FLAGS flags = native_logon_flags(LogonFlags);
556
557 HRESULT hr = E_FAIL;
558
559 create_mapi_session:
560 hr = MAPILogonEx(0,
561 (char*)MAPIProfileName,
562 (char*)(null_profile_passwd ? NULL : MAPIProfilePassword),
563 flags,
564 &mapi_session);
565 if (retry) {
566 if ((!profiles_on_disk_ && (MAPI_E_LOGON_FAILED == hr))
567 || (profiles_on_disk_ && (MAPI_E_NOT_FOUND == hr))) {
568 br = CreateProfile(MAPIProfileName,
569 MAPIProfilePassword,
570 MailboxName,
571 ServerName,
572 ServerType,
573 ProfileFlags,
574 (exchange_2007_ ? true : false));
575 if (::BRUTUS::BRUTUS_S_OK != br) {
576 BRUTUS_LOG_SUB_CRITICAL("Could not create MAPI Profile - Incorrect user credentials or insufficient privileges");
577 return br;
578 }
579 retry = false;
580 goto create_mapi_session;
581 }
582 }
583 if (!hresult_to_bresult(hr, br)) {
584 if (mapi_session) {
585 BRUTUS_LOG_SUB_ERR("MAPI session is non-NIL but MAPILogonEx failed.");
586 try {
587 mapi_session->Release();
588 }
589 catch (...) {
590 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
591 }
592 }
593 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
594 }
595 if (S_OK != hr) {
596 if (mapi_session) {
597 BRUTUS_LOG_SUB_ERR("MAPI session is non-NIL but MAPILogonEx failed.");
598 try {
599 mapi_session->Release();
600 }
601 catch (...) {
602 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
603 }
604 }
605 {
606 char msg[128] = {0};
607 const char *reason;
608
609 if (MAPI_E_TIMEOUT == hr)
610 reason = "MAPI_E_TIMEOUT";
611 else
612 reason = "MAPI_E_LOGON_FAILED";
613
614 sprintf_s(msg, sizeof(msg), "MAPILogonEx(%s) failed - %s", MAPIProfileName, reason);
615 BRUTUS_LOG_SUB_PRIVATE(msg);
616 }
617 return br;
618 }
619
620 // create the child poa for this mapi session
621 ::PortableServer::POA_var session_poa = ::PortableServer::POA::_nil();
622 again:
623 try {
624 session_poa = create_poa(MAPIProfileName,
625 ::PortableServer::POAManager::_nil(),
626 poa_.in());
627 }
628 catch (::PortableServer::POA::AdapterAlreadyExists &) {
629 BRUTUS_LOG_ERR("POA exists - terminating former instance, replacing with new...");
630 served_sessions_->sign_out(MAPIProfileName, 1);
631 goto again;
632 }
633 if (::CORBA::is_nil(session_poa)) {
634 BRUTUS_LOG_SUB_ERR("Could not create session POA");
635 try {
636 mapi_session->Release();
637 }
638 catch (...) {
639 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
640 }
641 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
642 }
643
644 // activate the IMAPISession object's poa so that requests can be served
645 ::PortableServer::POAManager_var poa_manager = session_poa->the_POAManager();
646 try {
647 poa_manager->activate();
648 }
649 catch (::PortableServer::POAManager::AdapterInactive &) {
650 BRUTUS_LOG_SUB_CRITICAL("POAManager::activate() throwed an exception");
651 try {
652 mapi_session->Release();
653 }
654 catch (...) {
655 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
656 }
657 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
658 }
659
660 // the session poa is now created so add it to the session registry
661 unsigned long id = served_sessions_->add_entry(session_poa.in(),
662 MAPIProfileName);
663 if (!id) {
664 BRUTUS_LOG_SUB_ERR("Could not add entry into managed sessions");
665
666 session_poa->destroy(1, 0);
667 try {
668 mapi_session->Release();
669 }
670 catch (...) {
671 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
672 }
673 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
674 }
675
676 // create the IMAPISession servant
677 BRUTUS_IMAPISession_i *mapi_session_servant;
678 try {
679 mapi_session_servant = new BRUTUS_IMAPISession_i(mapi_session,
680 session_poa.in(),
681 served_sessions_,
682 id,
683 internal_orb_.in(),
684 LifeLine,
685 CheckLifeDelay,
686 false);
687 }
688 catch (std::bad_alloc &) {
689 BRUTUS_LOG_SUB_ERR("No memory");
690
691 served_sessions_->sign_out(id, 0);
692 try {
693 mapi_session->Release();
694 }
695 catch (...) {
696 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
697 }
698 return ::BRUTUS::BRUTUS_MAPI_E_NOT_ENOUGH_MEMORY;
699 }
700
701 // create the IMAPISession object and register it in the session poa
702 ::PortableServer::ObjectId_var oid;
703 try {
704 ::PortableServer::ServantBase_var owner_transfer(mapi_session_servant);
705 oid = session_poa->activate_object(mapi_session_servant);
706 }
707 catch (const ::PortableServer::POA::WrongPolicy &) {
708 BRUTUS_LOG_SUB_CRITICAL("::PortableServer::POA::WrongPolicy exception caught");
709 served_sessions_->sign_out(id, 0);
710 try {
711 mapi_session->Release();
712 }
713 catch (...) {
714 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
715 }
716 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
717 }
718 catch (const ::PortableServer::POA::ServantAlreadyActive &) {
719 BRUTUS_LOG_SUB_CRITICAL("::PortableServer::POA::ServantAlreadyActive exception caught");
720 served_sessions_->sign_out(id, 0);
721 try {
722 mapi_session->Release();
723 }
724 catch (...) {
725 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
726 }
727 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
728 }
729
730 // get the object reference
731 ::CORBA::Object_var obj = ::CORBA::Object::_nil();
732 try {
733 obj = session_poa->id_to_reference(oid.in());
734 }
735 catch (const ::PortableServer::POA::WrongPolicy &) {
736 BRUTUS_LOG_SUB_CRITICAL("::PortableServer::POA::WrongPolicy exception caught");
737 }
738 catch (const ::PortableServer::POA::ObjectNotActive &) {
739 BRUTUS_LOG_SUB_CRITICAL("::PortableServer::POA::ObjectNotActive exception caught");
740 }
741 if (::CORBA::is_nil(obj)) {
742 BRUTUS_LOG_SUB_CRITICAL("::PortableServer::POA::id_to_reference() returned NIL");
743 served_sessions_->sign_out(id, 0);
744 try {
745 mapi_session->Release();
746 }
747 catch (...) {
748 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
749 }
750 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
751 }
752 session = ::BRUTUS::IMAPISession::_narrow(obj);
753 if (::CORBA::is_nil(session)) {
754 BRUTUS_LOG_SUB_CRITICAL("::BRUTUS::IMAPISession::_narrow() returned NIL");
755 served_sessions_->sign_out(id, 0);
756 try {
757 mapi_session->Release();
758 }
759 catch (...) {
760 BRUTUS_LOG_SUB_CRITICAL("Exception caught");
761 }
762 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
763 }
764 Session = session._retn();
765
766 {
767 char msg[128] = {0};
768 sprintf_s(msg, sizeof(msg), "%s has logged on", MAPIProfileName);
769 BRUTUS_LOG_SUB_PRIVATE(msg);
770 }
771 br = ::BRUTUS::BRUTUS_S_OK;
772 }
773 BRUTUS_LOG_SUB_PRIVATE(MAPIProfileName);
774
775 BRUTUS_LOG_SUB_INF("Leaving BRUTUS_BrutusLogOn_i::Logon()");
776
777 return br;
778 }
779
780 ::BRUTUS::BRESULT BRUTUS_BrutusLogOn_i::CreateProfile(const char *MAPIProfileName,
781 const char *MAPIProfilePassword,
782 const char *MailboxName,
783 const char *ServerName,
784 ::BRUTUS::SERVER_TYPE ServerType,
785 ::BRUTUS::BDEFINE ProfileFlags,
786 ::CORBA::Boolean ConnectIgnoreNoPF)
787 {
788 BRUTUS_LOG_REF;
789 BRUTUS_LOG_SUB_INF("Entering BRUTUS_BrutusLogOn_i::CreateProfile()");
790
791 if (!MAPIProfileName)
792 return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
793 else if (strlen(MAPIProfileName) > 64)
794 return ::BRUTUS::BRUTUS_MAPI_E_STRING_TOO_LONG;
795 if (MAPIProfilePassword && (strlen(MAPIProfilePassword) > 64))
796 return ::BRUTUS::BRUTUS_MAPI_E_STRING_TOO_LONG;
797 if (!strlen(MAPIProfilePassword))
798 MAPIProfilePassword = NULL;
799
800 BRUTUS_LOG_SUB_PRIVATE(MAPIProfileName);
801 BRUTUS_LOG_SUB_PRIVATE(MailboxName);
802 BRUTUS_LOG_SUB_PRIVATE(ServerName);
803
804 const char *server_type = NULL;
805 const char *service_display_name = NULL;
806 LPPROFSECT lpProfSect = NULL;
807 LPPROFADMIN lpProfAdmin = NULL;
808 LPSERVICEADMIN lpSvcAdmin = NULL;
809 LPMAPITABLE lpMsgSvcTable = NULL;
810 SRestriction sres;
811 SPropValue SvcProps;
812 LPSRowSet lpSvcRows = NULL; // Rowset to hold results of table query.
813 SPropValue rgval[2]; // Property structure to hold values we want to set.
814 ::BRUTUS::BRESULT br = ::BRUTUS::BRUTUS_INTERNAL_ERROR;
815 HRESULT hr = S_OK;
816
817 // I am not entirely clear on this. I don't feel good about initializing MAPI
818 // several times in the same thread and this method is a one-time call anyway
819 // so I better just serialize it with a RW mutex.
820 ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
821
822 if (process_per_session_) {
823 MAPIINIT_0 mapi_init;
824
825 mapi_init.ulFlags = MAPI_MULTITHREAD_NOTIFICATIONS | MAPI_NT_SERVICE | (profiles_on_disk_ ? MAPI_TEMPORARY_PROFILES : 0);
826 mapi_init.ulVersion = MAPI_INIT_VERSION;
827 hr = MAPIInitialize(&mapi_init);
828 if (hr != S_OK) {
829 BRUTUS_LOG_SUB_CRITICAL("Could not initialize MAPI");
830 return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
831 }
832 BRUTUS_LOG_SUB_INF("MAPI is initialized");
833
834 }
835
836 FLAGS flags = native_create_profile_flags(ProfileFlags);
837
838 // This indicates columns we want returned from HrQueryAllRows.
839 SizedSPropTagArray(2, sptCols) = { 2, PR_SERVICE_NAME, PR_SERVICE_UID };
840
841 // Get an IProfAdmin interface.
842 hr = MAPIAdminProfiles(0, &lpProfAdmin);
843 if (hr != S_OK) {
844 BRUTUS_LOG_SUB_BUG("MAPIAdminProfiles() failed");
845 goto out;
846 }
847
848 // Create a new profile.
849 hr = lpProfAdmin->CreateProfile((char*)MAPIProfileName,
850 (char*)MAPIProfilePassword,
851 NULL,
852 flags);
853 if (hr != S_OK) {
854 char __msg[128] = { 0 };
855 sprintf_s(__msg, sizeof(__msg), "Could not create profile, HRESULT = %#.8lx (", hr);
856 strcat_s(__msg, sizeof(__msg) - strlen(__msg), hresult_to_str(hr));
857 strcat_s(__msg, sizeof(__msg) - strlen(__msg), ")");
858 BRUTUS_LOG_SUB_BUG(__msg);
859 goto out;
860 }
861
862 // Get an IMsgServiceAdmin interface off of the IProfAdmin interface.
863 hr = lpProfAdmin->AdminServices((char*)MAPIProfileName,
864 (char*)MAPIProfilePassword,
865 NULL,
866 flags,
867 &lpSvcAdmin);
868 if (hr != S_OK) {
869 BRUTUS_LOG_SUB_BUG("Could not get IMsgServiceAdmin interface");
870 goto out;
871 }
872