s3: libsmb: Change cli_getattrE() and async versions to return a 32-bit attribute.
[vlendec/samba-autobuild/.git] / source3 / utils / nmblookup.c
index 17fbd485aec41d65b35e85c899f65b77804b8c88..c74b6497a3544453768c40fc04f4c0c37fe879a7 100644 (file)
@@ -20,8 +20,9 @@
 */
 
 #include "includes.h"
-
-extern bool AllowDebugChange;
+#include "popt_common.h"
+#include "libsmb/nmblib.h"
+#include "libsmb/namequery.h"
 
 static bool give_flags = false;
 static bool use_bcast = true;
@@ -40,7 +41,7 @@ static bool find_status = false;
 static bool open_sockets(void)
 {
        struct sockaddr_storage ss;
-       const char *sock_addr = lp_socket_address();
+       const char *sock_addr = lp_nbt_client_socket_address();
 
        if (!interpret_string_addr(&ss, sock_addr,
                                AI_NUMERICHOST|AI_PASSIVE)) {
@@ -107,42 +108,45 @@ static char *query_flags(int flags)
  Do a node status query.
 ****************************************************************************/
 
-static void do_node_status(int fd,
-               const char *name,
+static bool do_node_status(const char *name,
                int type,
                struct sockaddr_storage *pss)
 {
        struct nmb_name nname;
        int count, i, j;
-       NODE_STATUS_STRUCT *status;
+       struct node_status *addrs;
        struct node_status_extra extra;
        fstring cleanname;
        char addr[INET6_ADDRSTRLEN];
+       NTSTATUS status;
 
        print_sockaddr(addr, sizeof(addr), pss);
        d_printf("Looking up status of %s\n",addr);
        make_nmb_name(&nname, name, type);
-       status = node_status_query(fd, &nname, pss, &count, &extra);
-       if (status) {
+       status = node_status_query(talloc_tos(), &nname, pss,
+                                  &addrs, &count, &extra);
+       if (NT_STATUS_IS_OK(status)) {
                for (i=0;i<count;i++) {
-                       pull_ascii_fstring(cleanname, status[i].name);
+                       pull_ascii_fstring(cleanname, addrs[i].name);
                        for (j=0;cleanname[j];j++) {
                                if (!isprint((int)cleanname[j])) {
                                        cleanname[j] = '.';
                                }
                        }
                        d_printf("\t%-15s <%02x> - %s\n",
-                              cleanname,status[i].type,
-                              node_status_flags(status[i].flags));
+                              cleanname,addrs[i].type,
+                              node_status_flags(addrs[i].flags));
                }
                d_printf("\n\tMAC Address = %02X-%02X-%02X-%02X-%02X-%02X\n",
                                extra.mac_addr[0], extra.mac_addr[1],
                                extra.mac_addr[2], extra.mac_addr[3],
                                extra.mac_addr[4], extra.mac_addr[5]);
                d_printf("\n");
-               SAFE_FREE(status);
+               TALLOC_FREE(addrs);
+               return true;
        } else {
                d_printf("No reply from %s\n\n",addr);
+               return false;
        }
 }
 
@@ -153,40 +157,26 @@ static void do_node_status(int fd,
 
 static bool query_one(const char *lookup, unsigned int lookup_type)
 {
-       int j, count, flags = 0;
+       int j, count;
+       uint8_t flags;
        struct sockaddr_storage *ip_list=NULL;
+       NTSTATUS status = NT_STATUS_NOT_FOUND;
 
        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);
+               status = name_query(lookup,lookup_type,use_bcast,
+                                   use_bcast?true:recursion_desired,
+                                   &bcast_addr, talloc_tos(),
+                                   &ip_list, &count, &flags);
        } 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);
-               }
+               status = name_resolve_bcast(
+                       lookup, lookup_type,
+                       talloc_tos(), &ip_list, &count);
        }
 
-       if (!ip_list) {
+       if (!NT_STATUS_IS_OK(status)) {
                return false;
        }
 
@@ -197,7 +187,7 @@ static bool query_one(const char *lookup, unsigned int lookup_type)
        for (j=0;j<count;j++) {
                char addr[INET6_ADDRSTRLEN];
                if (translate_addresses) {
-                       char h_name[HOST_NAME_MAX];
+                       char h_name[MAX_DNS_NAME_LENGTH];
                        h_name[0] = '\0';
                        if (sys_getnameinfo((const struct sockaddr *)&ip_list[j],
                                        sizeof(struct sockaddr_storage),
@@ -214,53 +204,119 @@ static bool query_one(const char *lookup, unsigned int lookup_type)
                   was valid - ie. name_query returned true.
                 */
                if (find_status) {
-                       do_node_status(ServerFD, lookup,
-                                       lookup_type, &ip_list[j]);
+                       if (!do_node_status(lookup, lookup_type, &ip_list[j])) {
+                               status = NT_STATUS_UNSUCCESSFUL;
+                       }
                }
        }
 
-       safe_free(ip_list);
+       TALLOC_FREE(ip_list);
 
-       return (ip_list != NULL);
+       return NT_STATUS_IS_OK(status);
 }
 
 
 /****************************************************************************
   main program
 ****************************************************************************/
-int main(int argc,char *argv[])
+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;
+       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" },
+               {
+                       .longName   = "broadcast",
+                       .shortName  = 'B',
+                       .argInfo    = POPT_ARG_STRING,
+                       .arg        = NULL,
+                       .val        = 'B',
+                       .descrip    = "Specify address to use for broadcasts",
+                       .argDescrip = "BROADCAST-ADDRESS",
+               },
+               {
+                       .longName   = "flags",
+                       .shortName  = 'f',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'f',
+                       .descrip    = "List the NMB flags returned",
+               },
+               {
+                       .longName   = "unicast",
+                       .shortName  = 'U',
+                       .argInfo    = POPT_ARG_STRING,
+                       .arg        = NULL,
+                       .val        = 'U',
+                       .descrip    = "Specify address to use for unicast",
+               },
+               {
+                       .longName   = "master-browser",
+                       .shortName  = 'M',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'M',
+                       .descrip    = "Search for a master browser",
+               },
+               {
+                       .longName   = "recursion",
+                       .shortName  = 'R',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'R',
+                       .descrip    = "Set recursion desired in package",
+               },
+               {
+                       .longName   = "status",
+                       .shortName  = 'S',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'S',
+                       .descrip    = "Lookup node status as well",
+               },
+               {
+                       .longName   = "translate",
+                       .shortName  = 'T',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'T',
+                       .descrip    = "Translate IP addresses into names",
+               },
+               {
+                       .longName   = "root-port",
+                       .shortName  = 'r',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'r',
+                       .descrip    = "Use root port 137 (Win95 only replies to this)",
+               },
+               {
+                       .longName   = "lookup-by-ip",
+                       .shortName  = 'A',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'A',
+                       .descrip    = "Do a node status on <name> as an IP Address",
+               },
                POPT_COMMON_SAMBA
                POPT_COMMON_CONNECTION
-               { 0, 0, 0, 0 }
+               POPT_TABLEEND
        };
 
        *lookup = 0;
 
-       load_case_tables();
+       smb_init_locale();
 
-       setup_logging(argv[0],True);
+       setup_logging(argv[0], DEBUG_STDOUT);
 
-       pc = poptGetContext("nmblookup", argc, (const char **)argv,
+       pc = poptGetContext("nmblookup", argc, argv,
                        long_options, POPT_CONTEXT_KEEP_FIRST);
 
        poptSetOtherOptionHelp(pc, "<NODE> ...");
@@ -311,31 +367,36 @@ int main(int argc,char *argv[])
 
        if(!poptPeekArg(pc)) {
                poptPrintUsage(pc, stderr, 0);
-               exit(1);
+               rc = 1;
+               goto out;
        }
 
-       if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
+       if (!lp_load_global(get_dyn_CONFIGFILE())) {
                fprintf(stderr, "Can't load %s - run testparm to debug it\n",
-                               dyn_CONFIGFILE);
+                               get_dyn_CONFIGFILE());
        }
 
        load_interfaces();
        if (!open_sockets()) {
-               return(1);
+               rc = 1;
+               goto out;
        }
 
        while(poptPeekArg(pc)) {
                char *p;
                struct in_addr ip;
+               size_t nbt_len;
 
                fstrcpy(lookup,poptGetArg(pc));
 
                if(lookup_by_ip) {
                        struct sockaddr_storage ss;
-                       ip = *interpret_addr2(lookup);
+                       ip = interpret_addr2(lookup);
                        in_addr_to_sockaddr_storage(&ss, ip);
                        fstrcpy(lookup,"*");
-                       do_node_status(ServerFD, lookup, lookup_type, &ss);
+                       if (!do_node_status(lookup, lookup_type, &ss)) {
+                               rc = 1;
+                       }
                        continue;
                }
 
@@ -354,7 +415,16 @@ int main(int argc,char *argv[])
                        sscanf(++p,"%x",&lookup_type);
                }
 
+               nbt_len = strlen(lookup);
+               if (nbt_len > MAX_NETBIOSNAME_LEN - 1) {
+                       d_printf("The specified netbios name [%s] is too long!\n",
+                                lookup);
+                       continue;
+               }
+
+
                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 );
@@ -363,7 +433,8 @@ int main(int argc,char *argv[])
                }
        }
 
+out:
        poptFreeContext(pc);
        TALLOC_FREE(frame);
-       return(0);
+       return rc;
 }