enum MAPISTATUS Logon(struct mapi_session *session, struct mapi_provider *provider, enum PROVIDER_ID provider_id) { struct mapi_context *mapi_ctx; NTSTATUS status; TALLOC_CTX *mem_ctx; struct dcerpc_pipe *pipe; struct mapi_profile *profile; char *binding; char *server; int retval = 0; enum MAPISTATUS mapistatus; /*Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = (TALLOC_CTX *)provider; profile = session->profile; mapi_ctx = session->mapi_ctx; switch(provider_id) { case PROVIDER_ID_EMSMDB: emsmdb_retry: binding = build_binding_string(mapi_ctx, mem_ctx, profile->server, profile); status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_emsmdb, mapi_ctx->lp_ctx); talloc_free(binding); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_LOGON_FAILED, NULL); switch (profile->exchange_version) { case 0x0: provider->ctx = emsmdb_connect(mem_ctx, session, pipe, profile->credentials, &retval); break; case 0x1: case 0x2: provider->ctx = emsmdb_connect_ex(mem_ctx, session, pipe, profile->credentials, &retval); break; } if (retval == ecNotEncrypted) { profile->seal = true; retval = 0; goto emsmdb_retry; } OPENCHANGE_RETVAL_IF(!provider->ctx, MAPI_E_LOGON_FAILED, NULL); if (server_version_at_least((struct emsmdb_context *)provider->ctx, 8, 0, 835, 0)) { struct emsmdb_context *prov_ctx = (struct emsmdb_context *)provider->ctx; status = dcerpc_secondary_context(pipe, &(prov_ctx->async_rpc_connection), &ndr_table_asyncemsmdb); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_LOGON_FAILED, NULL); mapistatus = emsmdb_async_connect(prov_ctx); OPENCHANGE_RETVAL_IF(mapistatus, mapistatus, NULL); session->notify_ctx = talloc_zero(prov_ctx->mem_ctx, struct mapi_notify_ctx); session->notify_ctx->notifications = talloc_zero((TALLOC_CTX *)session->notify_ctx, struct notifications); session->notify_ctx->notifications->prev = NULL; session->notify_ctx->notifications->next = NULL; } break; case PROVIDER_ID_NSPI: /* Call RfrGetNewDSA prior any NSPI call */ mapistatus = RfrGetNewDSA(mapi_ctx, session, profile->server, profile->mailbox, &server); if (mapistatus != MAPI_E_SUCCESS) { binding = build_binding_string(mapi_ctx, mem_ctx, profile->server, profile); } else { binding = build_binding_string(mapi_ctx, mem_ctx, server, profile); talloc_free(server); } status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_nsp, mapi_ctx->lp_ctx); talloc_free(binding); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND), ecRpcFailed, NULL); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_LOGON_FAILED, NULL); provider->ctx = (void *)nspi_bind(provider, pipe, profile->credentials, profile->codepage, profile->language, profile->method); OPENCHANGE_RETVAL_IF(!provider->ctx, MAPI_E_LOGON_FAILED, NULL); break; default: OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); break; } return MAPI_E_SUCCESS; }
bool torture_rpc_alter_context(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p, *p2, *p3; struct policy_handle *handle; struct ndr_interface_table tmptbl; bool ret = true; torture_comment(torture, "opening LSA connection\n"); status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "connecting"); torture_comment(torture, "Testing change of primary context\n"); status = dcerpc_alter_context(p, torture, &p->syntax, &p->transfer_syntax); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); if (!test_lsa_OpenPolicy2(p->binding_handle, torture, &handle)) { ret = false; } torture_comment(torture, "Testing change of primary context\n"); status = dcerpc_alter_context(p, torture, &p->syntax, &p->transfer_syntax); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); torture_comment(torture, "Opening secondary DSSETUP context\n"); status = dcerpc_secondary_context(p, &p2, &ndr_table_dssetup); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); torture_comment(torture, "Testing change of primary context\n"); status = dcerpc_alter_context(p2, torture, &p2->syntax, &p2->transfer_syntax); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); tmptbl = ndr_table_dssetup; tmptbl.syntax_id.if_version += 100; torture_comment(torture, "Opening bad secondary connection\n"); status = dcerpc_secondary_context(p, &p3, &tmptbl); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX, "dcerpc_alter_context with wrong version should fail"); torture_comment(torture, "Testing DSSETUP pipe operations\n"); ret &= test_DsRoleGetPrimaryDomainInformation(torture, p2); if (handle) { ret &= test_lsa_Close(p->binding_handle, torture, handle); } torture_comment(torture, "Testing change of primary context\n"); status = dcerpc_alter_context(p, torture, &p->syntax, &p->transfer_syntax); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); ret &= test_lsa_OpenPolicy2(p->binding_handle, torture, &handle); if (handle) { ret &= test_lsa_Close(p->binding_handle, torture, handle); } torture_comment(torture, "Testing change of primary context\n"); status = dcerpc_alter_context(p, torture, &p2->syntax, &p2->transfer_syntax); if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { ret &= test_lsa_OpenPolicy2_ex(p->binding_handle, torture, &handle, NT_STATUS_IO_DEVICE_ERROR); torture_assert(torture, !dcerpc_binding_handle_is_connected(p->binding_handle), "dcerpc disonnected"); return ret; } torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); torture_comment(torture, "Testing DSSETUP pipe operations - should fault\n"); ret &= test_DsRoleGetPrimaryDomainInformation_ext(torture, p, NT_STATUS_RPC_BAD_STUB_DATA); ret &= test_lsa_OpenPolicy2(p->binding_handle, torture, &handle); if (handle) { ret &= test_lsa_Close(p->binding_handle, torture, handle); } torture_comment(torture, "Testing DSSETUP pipe operations\n"); ret &= test_DsRoleGetPrimaryDomainInformation(torture, p2); return ret; }
BOOL torture_rpc_alter_context(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p, *p2; TALLOC_CTX *mem_ctx; BOOL ret = True; struct policy_handle *handle; struct dcerpc_interface_table tmptbl; struct dcerpc_syntax_id syntax; struct dcerpc_syntax_id transfer_syntax; mem_ctx = talloc_init("torture_rpc_alter_context"); printf("opening LSA connection\n"); status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_lsarpc); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return False; } if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) { ret = False; } printf("Opening secondary DSSETUP context\n"); status = dcerpc_secondary_context(p, &p2, &dcerpc_table_dssetup); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); printf("dcerpc_alter_context failed - %s\n", nt_errstr(status)); return False; } tmptbl = dcerpc_table_dssetup; tmptbl.syntax_id.if_version += 100; printf("Opening bad secondary connection\n"); status = dcerpc_secondary_context(p, &p2, &tmptbl); if (NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); printf("dcerpc_alter_context with wrong version should fail\n"); return False; } printf("testing DSSETUP pipe operations\n"); ret &= test_DsRoleGetPrimaryDomainInformation(p2, mem_ctx); if (handle) { if (!test_lsa_Close(p, mem_ctx, handle)) { ret = False; } } syntax = p->syntax; transfer_syntax = p->transfer_syntax; printf("Testing change of primary context\n"); status = dcerpc_alter_context(p, mem_ctx, &p2->syntax, &p2->transfer_syntax); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); printf("dcerpc_alter_context failed - %s\n", nt_errstr(status)); return False; } printf("testing DSSETUP pipe operations - should fault\n"); if (test_DsRoleGetPrimaryDomainInformation(p, mem_ctx)) { ret = False; } if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) { ret = False; } if (handle) { if (!test_lsa_Close(p, mem_ctx, handle)) { ret = False; } } printf("testing DSSETUP pipe operations\n"); ret &= test_DsRoleGetPrimaryDomainInformation(p2, mem_ctx); talloc_free(mem_ctx); return ret; }