static NTSTATUS check_trustdomain_security(const struct auth_context *auth_context, void *my_private_data, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info) { NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; fstring dc_name; struct sockaddr_storage dc_ss; if (!user_info || !server_info || !auth_context) { DEBUG(1,("check_trustdomain_security: Critical variables not present. Failing.\n")); return NT_STATUS_INVALID_PARAMETER; } DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); /* * Check that the requested domain is not our own machine name or domain name. */ if( strequal(get_global_sam_name(), user_info->mapped.domain_name)) { DEBUG(3,("check_trustdomain_security: Requested domain [%s] was for this machine.\n", user_info->mapped.domain_name)); return NT_STATUS_NOT_IMPLEMENTED; } /* No point is bothering if this is not a trusted domain. This return makes "map to guest = bad user" work again. The logic is that if we know nothing about the domain, that user is not known to us and does not exist */ if ( !is_trusted_domain( user_info->mapped.domain_name ) ) return NT_STATUS_NOT_IMPLEMENTED; /* use get_dc_name() for consistency even through we know that it will be a netbios name */ if ( !get_dc_name(user_info->mapped.domain_name, NULL, dc_name, &dc_ss) ) { DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n", user_info->mapped.domain_name)); return NT_STATUS_NO_LOGON_SERVERS; } nt_status = domain_client_validate(mem_ctx, user_info, user_info->mapped.domain_name, (uchar *)auth_context->challenge.data, server_info, dc_name, &dc_ss); return nt_status; }
NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info, const char *smb_name, const char *client_domain, const char *workstation_name, DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd, const struct samr_Password *lm_interactive_pwd, const struct samr_Password *nt_interactive_pwd, const char *plaintext, enum auth_password_state password_state) { const char *domain; NTSTATUS result; bool was_mapped; char *internal_username = NULL; was_mapped = map_username(talloc_tos(), smb_name, &internal_username); if (!internal_username) { return NT_STATUS_NO_MEMORY; } DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n", client_domain, smb_name, workstation_name)); domain = client_domain; /* If you connect to a Windows domain member using a bogus domain name, * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if * the Windows box is a DC the name will become DOMAIN\user and be * authenticated against AD, if the Windows box is a member server but * not a DC the name will become WORKSTATION\user. A standalone * non-domain member box will also map to WORKSTATION\user. * This also deals with the client passing in a "" domain */ if (!is_trusted_domain(domain) && !strequal(domain, my_sam_name()) && !strequal(domain, get_global_sam_name())) { if (lp_map_untrusted_to_domain()) domain = my_sam_name(); else domain = get_global_sam_name(); DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from " "workstation [%s]\n", client_domain, domain, smb_name, workstation_name)); } /* We know that the given domain is trusted (and we are allowing them), * it is our global SAM name, or for legacy behavior it is our * primary domain name */ result = make_user_info(user_info, smb_name, internal_username, client_domain, domain, workstation_name, lm_pwd, nt_pwd, lm_interactive_pwd, nt_interactive_pwd, plaintext, password_state); if (NT_STATUS_IS_OK(result)) { /* We have tried mapping */ (*user_info)->mapped_state = True; /* did we actually map the user to a different name? */ (*user_info)->was_mapped = was_mapped; } return result; }
NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u) { uint32 flags = 0x0; uint32 pdc_connection_status = 0x0; uint32 logon_attempts = 0x0; uint32 tc_status; fstring servername, domain, dc_name, dc_name2; struct in_addr dc_ip; /* this should be \\global_myname() */ unistr2_to_ascii(servername, &q_u->uni_server_name, sizeof(servername)); r_u->status = NT_STATUS_OK; tc_status = ERROR_NO_SUCH_DOMAIN; fstrcpy( dc_name, "" ); switch ( q_u->function_code ) { case NETLOGON_CONTROL_TC_QUERY: unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); if ( !is_trusted_domain( domain ) ) break; if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) { tc_status = ERROR_NO_LOGON_SERVERS; break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); tc_status = NO_ERROR; break; case NETLOGON_CONTROL_REDISCOVER: unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); if ( !is_trusted_domain( domain ) ) break; if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) { tc_status = ERROR_NO_LOGON_SERVERS; break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); tc_status = NO_ERROR; break; default: /* no idea what this should be */ DEBUG(0,("_net_logon_ctrl2: unimplemented function level [%d]\n", q_u->function_code)); } /* prepare the response */ init_net_r_logon_ctrl2( r_u, q_u->query_level, flags, pdc_connection_status, logon_attempts, tc_status, dc_name ); if (lp_server_role() == ROLE_DOMAIN_BDC) send_sync_message(); return r_u->status; }