NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain, const char *server, struct sockaddr_storage *pss, unsigned flags, struct cli_state **pcli) { char *server_name = NULL; struct sockaddr_storage server_ss; struct cli_state *cli = NULL; NTSTATUS nt_status; if ( !server || !pss ) { if (!net_find_server(c, domain, flags, &server_ss, &server_name)) { d_fprintf(stderr, _("Unable to find a suitable server " "for domain %s\n"), domain); nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } } else { server_name = SMB_STRDUP( server ); server_ss = *pss; } if (flags & NET_FLAGS_ANONYMOUS) { nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss, server_name); } else { nt_status = connect_to_ipc(c, &cli, &server_ss, server_name); } /* store the server in the affinity cache if it was a PDC */ if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) ) saf_store( cli->server_domain, cli->desthost ); SAFE_FREE(server_name); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, _("Connection failed: %s\n"), nt_errstr(nt_status)); cli = NULL; } else if (c->opt_request_timeout) { cli_set_timeout(cli, c->opt_request_timeout * 1000); } done: if (pcli != NULL) { *pcli = cli; } return nt_status; }
struct cli_state *net_make_ipc_connection_ex( const char *domain, const char *server, struct in_addr *ip, unsigned flags) { char *server_name = NULL; struct in_addr server_ip; struct cli_state *cli = NULL; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; if ( !server || !ip ) { if (!net_find_server(domain, flags, &server_ip, &server_name)) { d_fprintf(stderr, "Unable to find a suitable server\n"); return NULL; } } else { server_name = SMB_STRDUP( server ); server_ip = *ip; } if (opt_user_name) { nt_status = connect_to_ipc(&cli, &server_ip, server_name); if (NT_STATUS_IS_OK(nt_status)) { goto connected; } } if (flags & NET_FLAGS_ANONYMOUS) { nt_status = connect_to_ipc_anonymous(&cli, &server_ip, server_name); if (NT_STATUS_IS_OK(nt_status)) { goto connected; } } SAFE_FREE(server_name); d_fprintf(stderr, "Connection failed: %s\n", nt_errstr(nt_status)); return NULL; connected: /* store the server in the affinity cache if it was a PDC */ if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) ) saf_store( cli->server_domain, cli->desthost ); return cli; }
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, const char *domain, uchar chal[8], struct auth_serversupplied_info **server_info, const char *dc_name, const struct sockaddr_storage *dc_ss) { TALLOC_CTX *frame = talloc_stackframe(); struct netr_SamInfo3 *info3 = NULL; struct cli_state *cli = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; struct netlogon_creds_cli_context *netlogon_creds = NULL; NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS; int i; uint8_t authoritative = 0; uint32_t flags = 0; /* * At this point, smb_apasswd points to the lanman response to * the challenge in local_challenge, and smb_ntpasswd points to * the NT response to the challenge in local_challenge. Ship * these over the secure channel to a domain controller and * see if they were valid. */ /* rety loop for robustness */ for (i = 0; !NT_STATUS_IS_OK(nt_status) && (i < 3); i++) { nt_status = connect_to_domain_password_server(&cli, domain, dc_name, dc_ss, &netlogon_pipe, frame, &netlogon_creds); } if ( !NT_STATUS_IS_OK(nt_status) ) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); TALLOC_FREE(frame); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { return NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE; } return nt_status; } /* store a successful connection */ saf_store(domain, dc_name); /* * If this call succeeds, we now have lots of info about the user * in the info3 structure. */ nt_status = rpccli_netlogon_network_logon(netlogon_creds, netlogon_pipe->binding_handle, mem_ctx, user_info->logon_parameters, /* flags such as 'allow workstation logon' */ user_info->client.account_name, /* user name logging on. */ user_info->client.domain_name, /* domain name */ user_info->workstation_name, /* workstation name */ chal, /* 8 byte challenge. */ user_info->password.response.lanman, /* lanman 24 byte response */ user_info->password.response.nt, /* nt 24 byte response */ &authoritative, &flags, &info3); /* info3 out */ /* Let go as soon as possible so we avoid any potential deadlocks with winbind lookup up users or groups. */ TALLOC_FREE(mutex); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " "Error was %s.\n", user_info->client.account_name, user_info->client.domain_name, dc_name, nt_errstr(nt_status))); /* map to something more useful */ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) { nt_status = NT_STATUS_NO_LOGON_SERVERS; } } else { nt_status = make_server_info_info3(mem_ctx, user_info->client.account_name, domain, server_info, info3); if (NT_STATUS_IS_OK(nt_status)) { (*server_info)->nss_token |= user_info->was_mapped; netsamlogon_cache_store(user_info->client.account_name, info3); TALLOC_FREE(info3); } } /* Note - once the cli stream is shutdown the mem_ctx used to allocate the other_sids and gids structures has been deleted - so these pointers are no longer valid..... */ cli_shutdown(cli); TALLOC_FREE(frame); return nt_status; }