static void msg_nmbd_send_packet(struct messaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { struct packet_struct *p = (struct packet_struct *)data->data; struct subnet_record *subrec; struct sockaddr_storage ss; const struct sockaddr_storage *pss; const struct in_addr *local_ip; DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src))); if (data->length != sizeof(struct packet_struct)) { DEBUG(2, ("Discarding invalid packet length from %u\n", (unsigned int)procid_to_pid(&src))); return; } if ((p->packet_type != NMB_PACKET) && (p->packet_type != DGRAM_PACKET)) { DEBUG(2, ("Discarding invalid packet type from %u: %d\n", (unsigned int)procid_to_pid(&src), p->packet_type)); return; } in_addr_to_sockaddr_storage(&ss, p->ip); pss = iface_ip((struct sockaddr *)(void *)&ss); if (pss == NULL) { DEBUG(2, ("Could not find ip for packet from %u\n", (unsigned int)procid_to_pid(&src))); return; } local_ip = &((const struct sockaddr_in *)pss)->sin_addr; subrec = FIRST_SUBNET; p->recv_fd = -1; p->send_fd = (p->packet_type == NMB_PACKET) ? subrec->nmb_sock : subrec->dgram_sock; for (subrec = FIRST_SUBNET; subrec != NULL; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { if (ip_equal_v4(*local_ip, subrec->myip)) { p->send_fd = (p->packet_type == NMB_PACKET) ? subrec->nmb_sock : subrec->dgram_sock; break; } } if (p->packet_type == DGRAM_PACKET) { p->port = 138; p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr; p->packet.dgram.header.source_port = 138; } send_packet(p); }
bool is_local_net_v4(struct in_addr from) { struct sockaddr_storage ss; in_addr_to_sockaddr_storage(&ss, from); return is_local_net((struct sockaddr *)&ss); }
static void sync_child(char *name, int nm_type, char *workgroup, struct in_addr ip, bool local, bool servers, char *fname) { fstring unix_workgroup; struct cli_state *cli; uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0; struct sockaddr_storage ss; NTSTATUS status; /* W2K DMB's return empty browse lists on port 445. Use 139. * Patch from Andy Levine [email protected]. */ in_addr_to_sockaddr_storage(&ss, ip); status = cli_connect_nb(name, &ss, NBT_SMB_PORT, nm_type, get_local_machine_name(), SMB_SIGNING_DEFAULT, 0, &cli); if (!NT_STATUS_IS_OK(status)) { return; } status = cli_negprot(cli, PROTOCOL_NT1); if (!NT_STATUS_IS_OK(status)) { cli_shutdown(cli); return; } if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 1, "", 0, workgroup))) { cli_shutdown(cli); return; } if (!NT_STATUS_IS_OK(cli_tree_connect(cli, "IPC$", "IPC", "", 1))) { cli_shutdown(cli); return; } /* All the cli_XX functions take UNIX character set. */ fstrcpy(unix_workgroup, cli->server_domain ? cli->server_domain : workgroup); /* Fetch a workgroup list. */ cli_NetServerEnum(cli, unix_workgroup, local_type|SV_TYPE_DOMAIN_ENUM, callback, NULL); /* Now fetch a server list. */ if (servers) { fstrcpy(unix_workgroup, workgroup); cli_NetServerEnum(cli, unix_workgroup, local?SV_TYPE_LOCAL_LIST_ONLY:SV_TYPE_ALL, callback, NULL); } cli_shutdown(cli); }
/* IPADDR_INFO_LIST */ static bool AsyncNotify_Move(TALLOC_CTX *mem_ctx, const uint8_t **ptr) { const uint8_t *pos = *ptr; uint32_t length = IVAL(pos,0); /* uint32_t reserved = IVAL(pos,4); */ uint32_t num = IVAL(pos,8); uint32_t n; pos += 12; for (n=0; n<num; n++) { uint32_t flags = IVAL(pos,0); struct in_addr ipv4; struct in6_addr ipv6; struct sockaddr_storage sas4, sas6; char *str4, *str6; pos += 4; ipv4.s_addr = *((const in_addr_t*)pos); in_addr_to_sockaddr_storage(&sas4, ipv4); str4 = print_canonical_sockaddr(mem_ctx, &sas4); pos += 4; memcpy(&ipv6.s6_addr, pos, 16); in6_addr_to_sockaddr_storage(&sas6, ipv6); str6 = print_canonical_sockaddr(mem_ctx, &sas6); pos += 16; d_printf("Flags 0x%08x", flags); if (flags & IPADDR_V4) { d_printf(" %s", str4); } if (flags & IPADDR_V6) { d_printf(" %s", str6); } if (flags & IPADDR_ONLINE) { d_printf(" Online"); } if (flags & IPADDR_ONLINE) { d_printf(" Offline"); } d_printf("\n"); TALLOC_FREE(str4); TALLOC_FREE(str6); } if (pos - *ptr == length) { *ptr = pos; return true; } return false; }
/* check to see if smbd is running on localhost by trying to open a connection then closing it */ bool smbd_running(void) { struct in_addr loopback_ip; NTSTATUS status; struct cli_state *cli; struct sockaddr_storage ss; loopback_ip.s_addr = htonl(INADDR_LOOPBACK); in_addr_to_sockaddr_storage(&ss, loopback_ip); status = cli_connect_nb("localhost", &ss, 0, 0x20, lp_netbios_name(), Undefined, 0, &cli); if (!NT_STATUS_IS_OK(status)) { return false; } cli_shutdown(cli); return True; }
/* check to see if nmbd is running on localhost by looking for a __SAMBA__ response */ bool nmbd_running(void) { struct in_addr loopback_ip; int count; struct sockaddr_storage *ss_list; struct sockaddr_storage ss; NTSTATUS status; loopback_ip.s_addr = htonl(INADDR_LOOPBACK); in_addr_to_sockaddr_storage(&ss, loopback_ip); status = name_query("__SAMBA__", 0, True, True, &ss, talloc_tos(), &ss_list, &count, NULL); if (NT_STATUS_IS_OK(status)) { TALLOC_FREE(ss_list); return True; } return False; }
/**************************************************************************** main program ****************************************************************************/ int main(int argc, const char *argv[]) { int opt; unsigned int lookup_type = 0x0; fstring lookup; static bool find_master=False; static bool lookup_by_ip = False; poptContext pc = NULL; TALLOC_CTX *frame = talloc_stackframe(); int rc = 0; struct poptOption long_options[] = { POPT_AUTOHELP { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" }, { "flags", 'f', POPT_ARG_NONE, NULL, 'f', "List the NMB flags returned" }, { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" }, { "master-browser", 'M', POPT_ARG_NONE, NULL, 'M', "Search for a master browser" }, { "recursion", 'R', POPT_ARG_NONE, NULL, 'R', "Set recursion desired in package" }, { "status", 'S', POPT_ARG_NONE, NULL, 'S', "Lookup node status as well" }, { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" }, { "root-port", 'r', POPT_ARG_NONE, NULL, 'r', "Use root port 137 (Win95 only replies to this)" }, { "lookup-by-ip", 'A', POPT_ARG_NONE, NULL, 'A', "Do a node status on <name> as an IP Address" }, POPT_COMMON_SAMBA POPT_COMMON_CONNECTION { 0, 0, 0, 0 } }; *lookup = 0; load_case_tables(); setup_logging(argv[0], DEBUG_STDOUT); pc = poptGetContext("nmblookup", argc, argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "<NODE> ..."); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'f': give_flags = true; break; case 'M': find_master = true; break; case 'R': recursion_desired = true; break; case 'S': find_status = true; break; case 'r': RootPort = true; break; case 'A': lookup_by_ip = true; break; case 'B': if (interpret_string_addr(&bcast_addr, poptGetOptArg(pc), NI_NUMERICHOST)) { got_bcast = True; use_bcast = True; } break; case 'U': if (interpret_string_addr(&bcast_addr, poptGetOptArg(pc), 0)) { got_bcast = True; use_bcast = False; } break; case 'T': translate_addresses = !translate_addresses; break; } } poptGetArg(pc); /* Remove argv[0] */ if(!poptPeekArg(pc)) { poptPrintUsage(pc, stderr, 0); rc = 1; goto out; } if (!lp_load_global(get_dyn_CONFIGFILE())) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", get_dyn_CONFIGFILE()); } load_interfaces(); if (!open_sockets()) { rc = 1; goto out; } while(poptPeekArg(pc)) { char *p; struct in_addr ip; fstrcpy(lookup,poptGetArg(pc)); if(lookup_by_ip) { struct sockaddr_storage ss; ip = interpret_addr2(lookup); in_addr_to_sockaddr_storage(&ss, ip); fstrcpy(lookup,"*"); if (!do_node_status(lookup, lookup_type, &ss)) { rc = 1; } continue; } if (find_master) { if (*lookup == '-') { fstrcpy(lookup,"\01\02__MSBROWSE__\02"); lookup_type = 1; } else { lookup_type = 0x1d; } } p = strchr_m(lookup,'#'); if (p) { *p = '\0'; sscanf(++p,"%x",&lookup_type); } if (!query_one(lookup, lookup_type)) { rc = 1; d_printf( "name_query failed to find name %s", lookup ); if( 0 != lookup_type ) { d_printf( "#%02x", lookup_type ); } d_printf( "\n" ); } } out: poptFreeContext(pc); TALLOC_FREE(frame); return rc; }
static struct subnet_record *make_subnet(const char *name, enum subnet_type type, struct in_addr myip, struct in_addr bcast_ip, struct in_addr mask_ip) { struct subnet_record *subrec = NULL; int nmb_sock = -1; int dgram_sock = -1; int nmb_bcast = -1; int dgram_bcast = -1; bool bind_bcast = lp_nmbd_bind_explicit_broadcast(); /* Check if we are creating a non broadcast subnet - if so don't create sockets. */ if (type == NORMAL_SUBNET) { struct sockaddr_storage ss; struct sockaddr_storage ss_bcast; in_addr_to_sockaddr_storage(&ss, myip); in_addr_to_sockaddr_storage(&ss_bcast, bcast_ip); /* * Attempt to open the sockets on port 137/138 for this interface * and bind them. * Fail the subnet creation if this fails. */ nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port, 0, &ss, true); if (nmb_sock == -1) { DEBUG(0, ("nmbd_subnetdb:make_subnet()\n")); DEBUGADD(0,(" Failed to open nmb socket on interface %s ", inet_ntoa(myip))); DEBUGADD(0,("for port %d. ", global_nmb_port)); DEBUGADD(0,("Error was %s\n", strerror(errno))); goto failed; } set_socket_options(nmb_sock,"SO_BROADCAST"); set_blocking(nmb_sock, false); if (bind_bcast) { nmb_bcast = open_socket_in(SOCK_DGRAM, global_nmb_port, 0, &ss_bcast, true); if (nmb_bcast == -1) { DEBUG(0, ("nmbd_subnetdb:make_subnet()\n")); DEBUGADD(0,(" Failed to open nmb bcast socket on interface %s ", inet_ntoa(bcast_ip))); DEBUGADD(0,("for port %d. ", global_nmb_port)); DEBUGADD(0,("Error was %s\n", strerror(errno))); goto failed; } set_socket_options(nmb_bcast, "SO_BROADCAST"); set_blocking(nmb_bcast, false); } dgram_sock = open_socket_in(SOCK_DGRAM, DGRAM_PORT, 3, &ss, true); if (dgram_sock == -1) { DEBUG(0, ("nmbd_subnetdb:make_subnet()\n")); DEBUGADD(0,(" Failed to open dgram socket on interface %s ", inet_ntoa(myip))); DEBUGADD(0,("for port %d. ", DGRAM_PORT)); DEBUGADD(0,("Error was %s\n", strerror(errno))); goto failed; } set_socket_options(dgram_sock, "SO_BROADCAST"); set_blocking(dgram_sock, false); if (bind_bcast) { dgram_bcast = open_socket_in(SOCK_DGRAM, DGRAM_PORT, 3, &ss_bcast, true); if (dgram_bcast == -1) { DEBUG(0, ("nmbd_subnetdb:make_subnet()\n")); DEBUGADD(0,(" Failed to open dgram bcast socket on interface %s ", inet_ntoa(bcast_ip))); DEBUGADD(0,("for port %d. ", DGRAM_PORT)); DEBUGADD(0,("Error was %s\n", strerror(errno))); goto failed; } set_socket_options(dgram_bcast, "SO_BROADCAST"); set_blocking(dgram_bcast, false); } } subrec = SMB_MALLOC_P(struct subnet_record); if (!subrec) { DEBUG(0,("make_subnet: malloc fail !\n")); goto failed; } ZERO_STRUCTP(subrec); if((subrec->subnet_name = SMB_STRDUP(name)) == NULL) { DEBUG(0,("make_subnet: malloc fail for subnet name !\n")); goto failed; } DEBUG(2, ("making subnet name:%s ", name )); DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip))); DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip))); subrec->namelist_changed = False; subrec->work_changed = False; subrec->bcast_ip = bcast_ip; subrec->mask_ip = mask_ip; subrec->myip = myip; subrec->type = type; subrec->nmb_sock = nmb_sock; subrec->nmb_bcast = nmb_bcast; subrec->dgram_sock = dgram_sock; subrec->dgram_bcast = dgram_bcast; return subrec; failed: SAFE_FREE(subrec); if (nmb_sock != -1) { close(nmb_sock); } if (nmb_bcast != -1) { close(nmb_bcast); } if (dgram_sock != -1) { close(dgram_sock); } if (dgram_bcast != -1) { close(dgram_bcast); } return NULL; }
static void sync_child(char *name, int nm_type, char *workgroup, struct in_addr ip, bool local, bool servers, char *fname) { fstring unix_workgroup; struct cli_state *cli; uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0; struct nmb_name called, calling; struct sockaddr_storage ss; NTSTATUS status; /* W2K DMB's return empty browse lists on port 445. Use 139. * Patch from Andy Levine [email protected]. */ cli = cli_initialise(); if (!cli) { return; } if (!cli_set_port(cli, 139)) { cli_shutdown(cli); return; } in_addr_to_sockaddr_storage(&ss, ip); status = cli_connect(cli, name, &ss); if (!NT_STATUS_IS_OK(status)) { cli_shutdown(cli); return; } make_nmb_name(&calling, get_local_machine_name(), 0x0); make_nmb_name(&called , name, nm_type); if (!cli_session_request(cli, &calling, &called)) { cli_shutdown(cli); return; } if (!cli_negprot(cli)) { cli_shutdown(cli); return; } if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 1, "", 0, workgroup))) { cli_shutdown(cli); return; } if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { cli_shutdown(cli); return; } /* All the cli_XX functions take UNIX character set. */ fstrcpy(unix_workgroup, cli->server_domain ? cli->server_domain : workgroup); /* Fetch a workgroup list. */ cli_NetServerEnum(cli, unix_workgroup, local_type|SV_TYPE_DOMAIN_ENUM, callback, NULL); /* Now fetch a server list. */ if (servers) { fstrcpy(unix_workgroup, workgroup); cli_NetServerEnum(cli, unix_workgroup, local?SV_TYPE_LOCAL_LIST_ONLY:SV_TYPE_ALL, callback, NULL); } cli_shutdown(cli); }
int vscan_send_warning_message(const char *filename, const char *virname, const char *ipaddr) { struct in_addr ip; struct sockaddr_storage ss; struct nmb_name called, calling; pstring myname; pstring message; pstring shortfilename; char* lastslash; static pstring lastfile; static pstring lastip; #if SAMBA_VERSION_MAJOR==3 fstrcpy(remote_machine, get_remote_machine_name()); DEBUG(5, ("remote machine is: %s\n", remote_machine)); #endif /* Only notify once for a given virus/ip combo - otherwise the * scanner will go crazy reaccessing the file and sending * messages once the user hits the "okay" button */ if (strncmp(lastfile,filename,sizeof(pstring)) == 0) { if (strncmp(lastip,ipaddr,sizeof(pstring)) == 0) { DEBUG(5,("Both IP and Filename are the same, not notifying\n")); return 0; } } ZERO_ARRAY(lastfile); ZERO_ARRAY(lastip); pstrcpy(lastfile,filename); pstrcpy(lastip,ipaddr); ZERO_ARRAY(myname); pstrcpy(myname,myhostname()); ZERO_ARRAY(username); /* could make this configurable */ snprintf(username,sizeof(pstring)-1,"%s VIRUS SCANNER",myname); /* We need to get the real ip structure from the ip string * is this info already available somewhere else in samba? */ zero_ip_v4(&ip); if (inet_aton(ipaddr,&ip) == 0) { DEBUG(5,("Cannot resolve ip address %s\n", ipaddr)); return 1; } in_addr_to_sockaddr_storage(&ss, ip); make_nmb_name(&calling, myname, 0x0); make_nmb_name(&called , remote_machine, name_type); if (!(cli=cli_initialise())) { DEBUG(5,("Connection to %s failed\n", remote_machine)); return 1; } cli_set_port(cli, port); if (!NT_STATUS_IS_OK(cli_connect(cli, remote_machine, &ss))) { DEBUG(5,("Connection to %s failed\n", remote_machine)); return 1; } if (!cli_session_request(cli, &calling, &called)) { DEBUG(5,("session request failed\n")); cli_shutdown(cli); return 1; } ZERO_ARRAY(shortfilename); /* we don't want the entire filename, otherwise the message service may choke * so we chop off the path up to the very last forward-slash * assumption: unix-style pathnames in filename (don't know if there's a * portable file-separator variable... */ lastslash = strrchr(filename,'/'); if (lastslash != NULL && lastslash != filename) { pstrcpy(shortfilename,lastslash+1); } else { pstrcpy(shortfilename,filename); } ZERO_ARRAY(message); /* could make the message configurable and language specific? */ snprintf(message,sizeof(pstring)-1, "%s IS INFECTED WITH VIRUS %s.\r\n\r\nAccess will be denied.\r\nPlease contact your system administrator", shortfilename, virname); /* actually send the message... */ send_message(message); cli_shutdown(cli); return 0; }
static bool query_one(const char *lookup, unsigned int lookup_type) { int j, count, flags = 0; struct sockaddr_storage *ip_list=NULL; if (got_bcast) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &bcast_addr); d_printf("querying %s on %s\n", lookup, addr); ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast, use_bcast?true:recursion_desired, &bcast_addr, &count, &flags, NULL); } else { const struct in_addr *bcast; for (j=iface_count() - 1; !ip_list && j >= 0; j--) { char addr[INET6_ADDRSTRLEN]; struct sockaddr_storage bcast_ss; bcast = iface_n_bcast_v4(j); if (!bcast) { continue; } in_addr_to_sockaddr_storage(&bcast_ss, *bcast); print_sockaddr(addr, sizeof(addr), &bcast_ss); d_printf("querying %s on %s\n", lookup, addr); ip_list = name_query(ServerFD,lookup,lookup_type, use_bcast, use_bcast?True:recursion_desired, &bcast_ss,&count, &flags, NULL); } } if (!ip_list) { return false; } if (give_flags) { d_printf("Flags: %s\n", query_flags(flags)); } for (j=0;j<count;j++) { char addr[INET6_ADDRSTRLEN]; if (translate_addresses) { char h_name[MAX_DNS_NAME_LENGTH]; h_name[0] = '\0'; if (sys_getnameinfo((const struct sockaddr *)&ip_list[j], sizeof(struct sockaddr_storage), h_name, sizeof(h_name), NULL, 0, NI_NAMEREQD)) { continue; } d_printf("%s, ", h_name); } print_sockaddr(addr, sizeof(addr), &ip_list[j]); d_printf("%s %s<%02x>\n", addr,lookup, lookup_type); /* We can only do find_status if the ip address returned was valid - ie. name_query returned true. */ if (find_status) { do_node_status(ServerFD, lookup, lookup_type, &ip_list[j]); } } free(ip_list); return (ip_list != NULL); }
bool ismyip_v4(struct in_addr ip) { struct sockaddr_storage ss; in_addr_to_sockaddr_storage(&ss, ip); return ismyaddr((struct sockaddr *)&ss); }