struct cli_state *get_ipc_connect_master_ip(pstring workgroup, struct user_auth_info *user_info, struct in_addr *mb_ip) { fstring name; struct cli_state *cli; struct in_addr server_ss; /* * Do a name status query to find out the name of the master browser. * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain * master browser will not respond to a wildcard query (or, at least, * an NT4 server acting as the domain master browser will not). * * We might be able to use ONLY the query on MSBROWSE, but that's not * yet been tested with all Windows versions, so until it is, leave * the original wildcard query as the first choice and fall back to * MSBROWSE if the wildcard query fails. */ if (!name_status_find("*", 0, 0x1d, *mb_ip, name) && !name_status_find(MSBROWSE, 1, 0x1d, *mb_ip, name)) return NULL; if (!find_master_ip(name, &server_ss)) return NULL; pstrcpy(workgroup, name); DEBUG(4, ("found master browser %s, %s\n", name, inet_ntoa(*mb_ip))); cli = get_ipc_connect(inet_ntoa(server_ss), &server_ss, user_info); return cli; }
static BOOL get_servers(char *workgroup, struct user_auth_info *user_info) { struct cli_state *cli; struct in_addr server_ip; /* Open an IPC$ connection to the master browser for the workgroup */ if (!find_master_ip(workgroup, &server_ip)) { DEBUG(4, ("Cannot find master browser for workgroup %s\n", workgroup)); return False; } if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info))) return False; if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name, &servers)) { if(cli) cli_shutdown(cli); return False; } if(cli)cli_shutdown(cli); return True; }
static int net_lookup_master(int argc, const char **argv) { struct in_addr master_ip; const char *domain=opt_target_workgroup; if (argc > 0) domain=argv[0]; if (!find_master_ip(domain, &master_ip)) return -1; d_printf("%s\n", inet_ntoa(master_ip)); return 0; }
/**************************************************************************** display tree of smb workgroups, servers and shares ****************************************************************************/ static bool get_workgroups(struct user_auth_info *user_info) { struct cli_state *cli; struct sockaddr_storage server_ss; TALLOC_CTX *ctx = talloc_tos(); char *master_workgroup = NULL; /* Try to connect to a #1d name of our current workgroup. If that doesn't work broadcast for a master browser and then jump off that workgroup. */ master_workgroup = talloc_strdup(ctx, lp_workgroup()); if (!master_workgroup) { return false; } if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ss)) { DEBUG(4,("Unable to find master browser for workgroup %s, " "falling back to broadcast\n", master_workgroup)); use_bcast = true; } if (!use_bcast) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &server_ss); cli = get_ipc_connect(addr, &server_ss, user_info); if (cli == NULL) { return false; } } else { cli = get_ipc_connect_master_ip_bcast(talloc_tos(), user_info, &master_workgroup); if (cli == NULL) { DEBUG(4, ("Unable to find master browser by " "broadcast\n")); return false; } } if (!cli_NetServerEnum(cli, master_workgroup, SV_TYPE_DOMAIN_ENUM, add_name, &workgroups)) return False; return True; }
static int net_lookup_master(struct net_context *c, int argc, const char **argv) { struct sockaddr_storage master_ss; const char *domain = c->opt_target_workgroup; char addr[INET6_ADDRSTRLEN]; if (argc > 0) domain=argv[0]; if (!find_master_ip(domain, &master_ss)) return -1; print_sockaddr(addr, sizeof(addr), &master_ss); d_printf("%s\n", addr); return 0; }
/**************************************************************************** display tree of smb workgroups, servers and shares ****************************************************************************/ static BOOL get_workgroups(struct user_auth_info *user_info) { struct cli_state *cli, *cli2; struct in_addr server_ip; pstring master_workgroup; /* Try to connect to a #1d name of our current workgroup. If that doesn't work broadcast for a master browser and then jump off that workgroup. */ pstrcpy(master_workgroup, lp_workgroup()); if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ip)) { DEBUG(4, ("Unable to find master browser for workgroup %s, falling back to broadcast\n", master_workgroup)); use_bcast = True; } else if(!use_bcast) { if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info))) return False; } if (!(cli2 = get_ipc_connect_master_ip_bcast(master_workgroup, user_info))) { DEBUG(4, ("Unable to find master browser by " "broadcast\n")); if(cli) cli_shutdown(cli); return False; } if(cli2) { if(cli) cli_shutdown(cli); cli = cli2; } if (!cli_NetServerEnum(cli, master_workgroup, SV_TYPE_DOMAIN_ENUM, add_name, &workgroups)) { if(cli) cli_shutdown(cli); return False; } if(cli) cli_shutdown(cli); return True; }
static bool get_servers(char *workgroup, struct user_auth_info *user_info) { struct cli_state *cli; struct sockaddr_storage server_ss; char addr[INET6_ADDRSTRLEN]; /* Open an IPC$ connection to the master browser for the workgroup */ if (!find_master_ip(workgroup, &server_ss)) { DEBUG(4, ("Cannot find master browser for workgroup %s\n", workgroup)); return False; } print_sockaddr(addr, sizeof(addr), &server_ss); if (!(cli = get_ipc_connect(addr, &server_ss, user_info))) return False; if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name, &servers)) return False; return True; }
/***************************************************** return a connection to a server (existing or new) *******************************************************/ struct smbw_server *smbw_server(char *server, char *share) { struct smbw_server *srv=NULL; struct cli_state c; char *username; char *password; char *workgroup; struct nmb_name called, calling; char *p, *server_n = server; fstring group; pstring ipenv; struct in_addr ip; zero_ip(&ip); ZERO_STRUCT(c); get_auth_data_fn(server, share, &workgroup, &username, &password); /* try to use an existing connection */ for (srv=smbw_srvs;srv;srv=srv->next) { if (strcmp(server,srv->server_name)==0 && strcmp(share,srv->share_name)==0 && strcmp(workgroup,srv->workgroup)==0 && strcmp(username, srv->username) == 0) return srv; } if (server[0] == 0) { errno = EPERM; return NULL; } make_nmb_name(&calling, global_myname, 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server)); if ((p=strchr(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { struct in_addr sip; pstring s; fstrcpy(group, server_n); p = strchr(group,'#'); *p = 0; /* cache the workgroup master lookup */ slprintf(s,sizeof(s)-1,"MASTER_%s", group); if (!(server_n = smbw_getshared(s))) { if (!find_master_ip(group, &sip)) { errno = ENOENT; return NULL; } fstrcpy(group, inet_ntoa(sip)); server_n = group; smbw_setshared(s,server_n); } } DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); zero_ip(&ip); if ((p=smbw_getshared(ipenv))) { ip = *(interpret_addr2(p)); } /* have to open a new connection */ if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { errno = ENOENT; return NULL; } if (!cli_session_request(&c, &calling, &called)) { cli_shutdown(&c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } errno = ENOENT; return NULL; } DEBUG(4,(" session request ok\n")); if (!cli_negprot(&c)) { cli_shutdown(&c); errno = ENOENT; return NULL; } if (!cli_session_setup(&c, username, password, strlen(password), password, strlen(password), workgroup) && /* try an anonymous login if it failed */ !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) { cli_shutdown(&c); errno = EPERM; return NULL; } DEBUG(4,(" session setup ok\n")); if (!cli_send_tconX(&c, share, "?????", password, strlen(password)+1)) { errno = smbw_errno(&c); cli_shutdown(&c); return NULL; } smbw_setshared(ipenv,inet_ntoa(ip)); DEBUG(4,(" tconx ok\n")); srv = (struct smbw_server *)malloc(sizeof(*srv)); if (!srv) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(srv); srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->server_name = strdup(server); if (!srv->server_name) { errno = ENOMEM; goto failed; } srv->share_name = strdup(share); if (!srv->share_name) { errno = ENOMEM; goto failed; } srv->workgroup = strdup(workgroup); if (!srv->workgroup) { errno = ENOMEM; goto failed; } srv->username = strdup(username); if (!srv->username) { errno = ENOMEM; goto failed; } /* some programs play with file descriptors fairly intimately. We try to get out of the way by duping to a high fd number */ if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) { if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) == srv->cli.fd+SMBW_CLI_FD) { close(srv->cli.fd); srv->cli.fd += SMBW_CLI_FD; } } DLIST_ADD(smbw_srvs, srv); return srv; failed: cli_shutdown(&c); if (!srv) return NULL; SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv); return NULL; }
/* display or set the time on a host */ int net_time(struct net_context *c, int argc, const char **argv) { time_t t; struct functable func[] = { { "system", net_time_system, NET_TRANSPORT_LOCAL, N_("Display time ready for /bin/date"), N_("net time system\n" " Display time ready for /bin/date") }, { "set", net_time_set, NET_TRANSPORT_LOCAL, N_("Set the system time from time server"), N_("net time set\n" " Set the system time from time server") }, { "zone", net_time_zone, NET_TRANSPORT_LOCAL, N_("Display timezone offset from UTC"), N_("net time zone\n" " Display timezone offset from UTC") }, {NULL, NULL, 0, NULL, NULL} }; if (argc != 0) { return net_run_function(c, argc, argv, "net time", func); } if (c->display_usage) { d_printf( "%s\n" "net time\n" " %s\n", _("Usage:"), _("Display the remote time server's time")); net_display_usage_from_functable(func); return 0; } if (c->opt_host == NULL && !c->opt_have_ip) { bool ok; ok = find_master_ip(c->opt_target_workgroup, &c->opt_dest_ip); if (!ok) { d_fprintf(stderr, _("Could not locate a time server. " "Try specifying a target host.\n")); net_time_usage(c, argc, argv); return -1; } c->opt_have_ip = true; } /* default - print the time */ t = cli_servertime(c->opt_host, c->opt_have_ip? &c->opt_dest_ip : NULL, NULL); if (t == 0) return -1; d_printf("%s", ctime(&t)); return 0; }