TALLOC_FREE(te);
}
-struct nmbd_proxy_logon_context {
- struct cldap_socket *cldap_sock;
-};
-
-static struct nmbd_proxy_logon_context *global_nmbd_proxy_logon;
-
-bool initialize_nmbd_proxy_logon(void)
-{
- const char *cldap_server = lp_parm_const_string(-1, "nmbd_proxy_logon",
- "cldap_server", NULL);
- struct nmbd_proxy_logon_context *ctx;
- NTSTATUS status;
- struct in_addr addr;
- char addrstr[INET_ADDRSTRLEN];
- const char *server_str;
- int ret;
- struct tsocket_address *server_addr;
-
- if (!cldap_server) {
- return true;
- }
-
- addr = interpret_addr2(cldap_server);
- server_str = inet_ntop(AF_INET, &addr,
- addrstr, sizeof(addrstr));
- if (!server_str || strcmp("0.0.0.0", server_str) == 0) {
- DEBUG(0,("Failed to resolve[%s] for nmbd_proxy_logon\n",
- cldap_server));
- return false;
- }
-
- ctx = talloc_zero(nmbd_event_context(),
- struct nmbd_proxy_logon_context);
- if (!ctx) {
- return false;
- }
-
- ret = tsocket_address_inet_from_strings(ctx, "ipv4",
- server_str, LDAP_PORT,
- &server_addr);
- if (ret != 0) {
- TALLOC_FREE(ctx);
- status = map_nt_error_from_unix(errno);
- DEBUG(0,("Failed to create cldap tsocket_address for %s - %s\n",
- server_str, nt_errstr(status)));
- return false;
- }
-
- /* we create a connected udp socket */
- status = cldap_socket_init(ctx, NULL, server_addr, &ctx->cldap_sock);
- TALLOC_FREE(server_addr);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(ctx);
- DEBUG(0,("failed to create cldap socket for %s: %s\n",
- server_str, nt_errstr(status)));
- return false;
- }
-
- global_nmbd_proxy_logon = ctx;
- return true;
-}
-
-struct nmbd_proxy_logon_state {
- struct in_addr local_ip;
- struct packet_struct *p;
- const char *remote_name;
- uint8_t remote_name_type;
- const char *remote_mailslot;
- struct nbt_netlogon_packet req;
- struct nbt_netlogon_response resp;
- struct cldap_netlogon io;
-};
-
-static int nmbd_proxy_logon_state_destructor(struct nmbd_proxy_logon_state *s)
-{
- s->p->locked = false;
- free_packet(s->p);
- return 0;
-}
-
-static void nmbd_proxy_logon_done(struct tevent_req *subreq);
-
-static void nmbd_proxy_logon(struct nmbd_proxy_logon_context *ctx,
- struct in_addr local_ip,
- struct packet_struct *p,
- const uint8_t *buf,
- uint32_t len)
-{
- struct nmbd_proxy_logon_state *state;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob = data_blob_const(buf, len);
- const char *computer_name = NULL;
- const char *mailslot_name = NULL;
- const char *user_name = NULL;
- const char *domain_sid = NULL;
- uint32_t acct_control = 0;
- uint32_t nt_version = 0;
- struct tevent_req *subreq;
- fstring source_name;
- struct dgram_packet *dgram = &p->packet.dgram;
-
- state = talloc_zero(ctx, struct nmbd_proxy_logon_state);
- if (!state) {
- DEBUG(0,("failed to allocate nmbd_proxy_logon_state\n"));
- return;
- }
-
- pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
- state->remote_name = talloc_strdup(state, source_name);
- state->remote_name_type = dgram->source_name.name_type,
- state->local_ip = local_ip;
- state->p = p;
-
- ndr_err = ndr_pull_struct_blob(
- &blob, state, &state->req,
- (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
- DEBUG(0,("failed parse nbt_netlogon_packet: %s\n",
- nt_errstr(status)));
- TALLOC_FREE(state);
- return;
- }
-
- if (DEBUGLEVEL >= 10) {
- DEBUG(10, ("nmbd_proxy_logon:\n"));
- NDR_PRINT_DEBUG(nbt_netlogon_packet, &state->req);
- }
-
- switch (state->req.command) {
- case LOGON_SAM_LOGON_REQUEST:
- computer_name = state->req.req.logon.computer_name;
- user_name = state->req.req.logon.user_name;
- mailslot_name = state->req.req.logon.mailslot_name;
- acct_control = state->req.req.logon.acct_control;
- if (state->req.req.logon.sid_size > 0) {
- domain_sid = dom_sid_string(state,
- &state->req.req.logon.sid);
- if (!domain_sid) {
- DEBUG(0,("failed to get a string for sid\n"));
- TALLOC_FREE(state);
- return;
- }
- }
- nt_version = state->req.req.logon.nt_version;
- break;
-
- default:
- /* this can't happen as the caller already checks the command */
- break;
- }
-
- state->remote_mailslot = mailslot_name;
-
- if (user_name && strlen(user_name) == 0) {
- user_name = NULL;
- }
-
- if (computer_name && strlen(computer_name) == 0) {
- computer_name = NULL;
- }
-
- /*
- * as the socket is connected,
- * we don't need to specify the destination
- */
- state->io.in.dest_address = NULL;
- state->io.in.dest_port = 0;
- state->io.in.realm = NULL;
- state->io.in.host = computer_name;
- state->io.in.user = user_name;
- state->io.in.domain_guid = NULL;
- state->io.in.domain_sid = domain_sid;
- state->io.in.acct_control = acct_control;
- state->io.in.version = nt_version;
- state->io.in.map_response = false;
-
- subreq = cldap_netlogon_send(state, nmbd_event_context(),
- ctx->cldap_sock,
- &state->io);
- if (!subreq) {
- DEBUG(0,("failed to send cldap netlogon call\n"));
- TALLOC_FREE(state);
- return;
- }
- tevent_req_set_callback(subreq, nmbd_proxy_logon_done, state);
-
- /* we reply async */
- state->p->locked = true;
- talloc_set_destructor(state, nmbd_proxy_logon_state_destructor);
-}
-
-static void nmbd_proxy_logon_done(struct tevent_req *subreq)
-{
- struct nmbd_proxy_logon_state *state =
- tevent_req_callback_data(subreq,
- struct nmbd_proxy_logon_state);
- NTSTATUS status;
- DATA_BLOB response = data_blob_null;
-
- status = cldap_netlogon_recv(subreq, state, &state->io);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("failed to recv cldap netlogon call: %s\n",
- nt_errstr(status)));
- TALLOC_FREE(state);
- return;
- }
-
- status = push_netlogon_samlogon_response(&response, state,
- &state->io.out.netlogon);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("failed to push netlogon_samlogon_response: %s\n",
- nt_errstr(status)));
- TALLOC_FREE(state);
- return;
- }
-
- send_mailslot(true, state->remote_mailslot,
- (char *)response.data, response.length,
- lp_netbios_name(), 0x0,
- state->remote_name,
- state->remote_name_type,
- state->p->ip,
- state->local_ip,
- state->p->port);
- TALLOC_FREE(state);
-}
-
/****************************************************************************
Process a domain logon packet
**************************************************************************/
struct netlogon_samlogon_response samlogon;
struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4;
- if (global_nmbd_proxy_logon) {
- nmbd_proxy_logon(global_nmbd_proxy_logon,
- ip, p, (const uint8_t *)buf, len);
- return;
- }
-
source_addr = SMB_STRDUP(inet_ntoa(dgram->header.source_ip));
if (source_addr == NULL) {
DEBUG(3, ("out of memory copying client"