/* Unix SMB/Netbios implementation. Version 2.2 RPC pipe client Copyright (C) Tim Potter 2000 Copyright (C) Andrew Tridgell 1992-1999 Copyright (C) Luke Kenneth Casson Leighton 1996-1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" extern int DEBUGLEVEL; extern pstring server; extern pstring global_myname; extern pstring username, password; extern pstring workgroup; /**************************************************************************** display sec_ace structure ****************************************************************************/ static void display_sec_ace(SEC_ACE *ace) { fstring sid_str; sid_to_string(sid_str, &ace->sid); printf("\t\tSID: %s\n", sid_str); printf("\t\ttype:[%d], flags:[0x%02x], mask:[0x%08x]\n", ace->type, ace->flags, ace->info.mask); } /**************************************************************************** display sec_acl structure ****************************************************************************/ static void display_sec_acl(SEC_ACL *acl) { if (acl->size != 0 && acl->num_aces != 0) { int i; printf("\t\tRevision:[%d]\n", acl->revision); for (i = 0; i < acl->num_aces; i++) { display_sec_ace(&acl->ace[i]); } } } /**************************************************************************** display sec_desc structure ****************************************************************************/ static void display_sec_desc(SEC_DESC *sec) { fstring sid_str; printf("\tRevision:[%d]\n", sec->revision); if (sec->off_owner_sid) { sid_to_string(sid_str, sec->owner_sid); printf("\tOwner SID: %s\n", sid_str); } if (sec->off_grp_sid) { sid_to_string(sid_str, sec->grp_sid); printf("\tGroup SID: %s\n", sid_str); } if (sec->off_sacl) display_sec_acl(sec->sacl); if (sec->off_dacl) display_sec_acl(sec->dacl); } /**************************************************************************** printer info level 0 display function ****************************************************************************/ static void display_print_info_0(PRINTER_INFO_0 *i1) { fstring name; fstring the_server; unistr_to_ascii(name, i1->printername.buffer, sizeof(name) - 1); unistr_to_ascii(server, i1->servername.buffer, sizeof(the_server) - 1); printf("\tprintername:[%s]\n", name); printf("\tservername:[%s]\n", the_server); printf("\tcjobs:[0x%x]\n", i1->cjobs); printf("\ttotal_jobs:[0x%x]\n", i1->total_jobs); printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i1->year, i1->month, i1->day, i1->dayofweek); printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i1->hour, i1->minute, i1->second, i1->milliseconds); printf("\tglobal_counter:[0x%x]\n", i1->global_counter); printf("\ttotal_pages:[0x%x]\n", i1->total_pages); printf("\tmajorversion:[0x%x]\n", i1->major_version); printf("\tbuildversion:[0x%x]\n", i1->build_version); printf("\tunknown7:[0x%x]\n", i1->unknown7); printf("\tunknown8:[0x%x]\n", i1->unknown8); printf("\tunknown9:[0x%x]\n", i1->unknown9); printf("\tsession_counter:[0x%x]\n", i1->session_counter); printf("\tunknown11:[0x%x]\n", i1->unknown11); printf("\tprinter_errors:[0x%x]\n", i1->printer_errors); printf("\tunknown13:[0x%x]\n", i1->unknown13); printf("\tunknown14:[0x%x]\n", i1->unknown14); printf("\tunknown15:[0x%x]\n", i1->unknown15); printf("\tunknown16:[0x%x]\n", i1->unknown16); printf("\tchange_id:[0x%x]\n", i1->change_id); printf("\tunknown18:[0x%x]\n", i1->unknown18); printf("\tstatus:[0x%x]\n", i1->status); printf("\tunknown20:[0x%x]\n", i1->unknown20); printf("\tc_setprinter:[0x%x]\n", i1->c_setprinter); printf("\tunknown22:[0x%x]\n", i1->unknown22); printf("\tunknown23:[0x%x]\n", i1->unknown23); printf("\tunknown24:[0x%x]\n", i1->unknown24); printf("\tunknown25:[0x%x]\n", i1->unknown25); printf("\tunknown26:[0x%x]\n", i1->unknown26); printf("\tunknown27:[0x%x]\n", i1->unknown27); printf("\tunknown28:[0x%x]\n", i1->unknown28); printf("\tunknown29:[0x%x]\n", i1->unknown29); } /**************************************************************************** printer info level 1 display function ****************************************************************************/ static void display_print_info_1(PRINTER_INFO_1 *i1) { fstring desc; fstring name; fstring comm; unistr_to_ascii(desc, i1->description.buffer, sizeof(desc) - 1); unistr_to_ascii(name, i1->name .buffer, sizeof(name) - 1); unistr_to_ascii(comm, i1->comment .buffer, sizeof(comm) - 1); printf("\tflags:[0x%x]\n", i1->flags); printf("\tname:[%s]\n", name); printf("\tdescription:[%s]\n", desc); printf("\tcomment:[%s]\n\n", comm); } /**************************************************************************** printer info level 2 display function ****************************************************************************/ static void display_print_info_2(PRINTER_INFO_2 *i2) { fstring servername; fstring printername; fstring sharename; fstring portname; fstring drivername; fstring comment; fstring location; fstring sepfile; fstring printprocessor; fstring datatype; fstring parameters; unistr_to_ascii(servername, i2->servername.buffer, sizeof(servername) - 1); unistr_to_ascii(printername, i2->printername.buffer, sizeof(printername) - 1); unistr_to_ascii(sharename, i2->sharename.buffer, sizeof(sharename) - 1); unistr_to_ascii(portname, i2->portname.buffer, sizeof(portname) - 1); unistr_to_ascii(drivername, i2->drivername.buffer, sizeof(drivername) - 1); unistr_to_ascii(comment, i2->comment.buffer, sizeof(comment) - 1); unistr_to_ascii(location, i2->location.buffer, sizeof(location) - 1); unistr_to_ascii(sepfile, i2->sepfile.buffer, sizeof(sepfile) - 1); unistr_to_ascii(printprocessor, i2->printprocessor.buffer, sizeof(printprocessor) - 1); unistr_to_ascii(datatype, i2->datatype.buffer, sizeof(datatype) - 1); unistr_to_ascii(parameters, i2->parameters.buffer, sizeof(parameters) - 1); printf("\tservername:[%s]\n", servername); printf("\tprintername:[%s]\n", printername); printf("\tsharename:[%s]\n", sharename); printf("\tportname:[%s]\n", portname); printf("\tdrivername:[%s]\n", drivername); printf("\tcomment:[%s]\n", comment); printf("\tlocation:[%s]\n", location); printf("\tsepfile:[%s]\n", sepfile); printf("\tprintprocessor:[%s]\n", printprocessor); printf("\tdatatype:[%s]\n", datatype); printf("\tparameters:[%s]\n", parameters); printf("\tattributes:[0x%x]\n", i2->attributes); printf("\tpriority:[0x%x]\n", i2->priority); printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority); printf("\tstarttime:[0x%x]\n", i2->starttime); printf("\tuntiltime:[0x%x]\n", i2->untiltime); printf("\tstatus:[0x%x]\n", i2->status); printf("\tcjobs:[0x%x]\n", i2->cjobs); printf("\taverageppm:[0x%x]\n", i2->averageppm); if (i2->secdesc) display_sec_desc(i2->secdesc); } /**************************************************************************** printer info level 3 display function ****************************************************************************/ static void display_print_info_3(PRINTER_INFO_3 *i3) { printf("\tflags:[0x%x]\n", i3->flags); display_sec_desc(i3->secdesc); } /* Enumerate printers */ static uint32 cmd_spoolss_enum_printers(int argc, char **argv) { uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1; struct cli_state cli; struct ntuser_creds creds; PRINTER_INFO_CTR ctr; int returned; if (argc > 2) { printf("Usage: enumprinters\n"); return NT_STATUS_NOPROBLEMO; } if (argc == 2) { info_level = atoi(argv[1]); } /* Initialise RPC connection */ ZERO_STRUCT(cli); init_rpcclient_creds(&creds); if (cli_spoolss_initialise(&cli, server, &creds) == NULL) { goto done; } /* Enumerate printers */ ZERO_STRUCT(ctr); result = cli_spoolss_enum_printers(&cli, PRINTER_ENUM_LOCAL, info_level, &returned, &ctr); if (result == NT_STATUS_NOPROBLEMO) { switch(info_level) { case 0: display_print_info_0(ctr.printers_0); break; case 1: display_print_info_1(ctr.printers_1); break; case 2: display_print_info_2(ctr.printers_2); break; case 3: display_print_info_3(ctr.printers_3); break; default: printf("unknown info level %d\n", info_level); break; } } done: cli_spoolss_shutdown(&cli); return result; } /**************************************************************************** port info level 1 display function ****************************************************************************/ static void display_port_info_1(PORT_INFO_1 *i1) { fstring buffer; unistr_to_ascii(buffer, i1->port_name.buffer, sizeof(buffer)-1); printf("\tPort Name:\t[%s]\n", buffer); } /**************************************************************************** port info level 2 display function ****************************************************************************/ static void display_port_info_2(PORT_INFO_2 *i2) { fstring buffer; unistr_to_ascii(buffer, i2->port_name.buffer, sizeof(buffer) - 1); printf("\tPort Name:\t[%s]\n", buffer); unistr_to_ascii(buffer, i2->monitor_name.buffer, sizeof(buffer) - 1); printf("\tMonitor Name:\t[%s]\n", buffer); unistr_to_ascii(buffer, i2->description.buffer, sizeof(buffer) - 1); printf("\tDescription:\t[%s]\n", buffer); printf("\tPort Type:\t[%d]\n", i2->port_type); printf("\tReserved:\t[%d]\n", i2->reserved); printf("\n"); } /* Enumerate ports */ static uint32 cmd_spoolss_enum_ports(int argc, char **argv) { uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1; struct cli_state cli; struct ntuser_creds creds; PORT_INFO_CTR ctr; int returned; if (argc == 1 || argc < 2) { printf("Usage: enumports [level]\n"); return NT_STATUS_NOPROBLEMO; } if (argc == 2) { info_level = atoi(argv[1]); } /* Initialise RPC connection */ ZERO_STRUCT(cli); init_rpcclient_creds(&creds); if (cli_spoolss_initialise(&cli, server, &creds) == NULL) { goto done; } /* Enumerate printers */ ZERO_STRUCT(ctr); result = cli_spoolss_enum_ports(&cli, info_level, &returned, &ctr); if (result == NT_STATUS_NOPROBLEMO) { int i; for (i = 0; i < returned; i++) { switch (info_level) { case 1: display_port_info_1(&ctr.port.info_1[i]); break; case 2: display_port_info_2(&ctr.port.info_2[i]); break; default: printf("unknown info level %d\n", info_level); break; } } } done: cli_spoolss_shutdown(&cli); return result; } /* Get printer information */ static uint32 cmd_spoolss_getprinter(int argc, char **argv) { struct cli_state cli; POLICY_HND pol; uint32 result, info_level = 1; BOOL opened_hnd = False; struct ntuser_creds creds; PRINTER_INFO_CTR ctr; fstring printer_name, station_name; if (argc == 1 || argc > 3) { printf("Usage: %s printername [level]\n", argv[0]); return NT_STATUS_NOPROBLEMO; } /* Initialise RPC connection */ ZERO_STRUCT(cli); init_rpcclient_creds(&creds); if (cli_spoolss_initialise(&cli, server, &creds) == NULL) { goto done; } /* Open a printer handle */ if (argc == 3) { info_level = atoi(argv[2]); } slprintf(printer_name, sizeof(fstring), "\\\\%s\\%s", server, argv[1]); slprintf(station_name, sizeof(fstring), "\\\\%s", global_myname); if ((result = cli_spoolss_open_printer_ex( &cli, printer_name, "", MAXIMUM_ALLOWED_ACCESS, station_name, username, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; } opened_hnd = True; /* Get printer info */ if ((result = cli_spoolss_getprinter(&cli, &pol, info_level, &ctr)) != NT_STATUS_NOPROBLEMO) { goto done; } /* Display printer info */ switch (info_level) { case 0: display_print_info_0(ctr.printers_0); break; case 1: display_print_info_1(ctr.printers_1); break; case 2: display_print_info_2(ctr.printers_2); break; case 3: display_print_info_3(ctr.printers_3); break; default: printf("unknown info level %d\n", info_level); break; } done: if (opened_hnd) cli_spoolss_closeprinter(&cli, &pol); cli_spoolss_shutdown(&cli); return result; } /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { { "enumprinters", cmd_spoolss_enum_printers, "Enumerate printers" }, { "enumports", cmd_spoolss_enum_ports, "Enumerate printer ports" }, { "getprinter", cmd_spoolss_getprinter, "Get printer info" }, { NULL, NULL, NULL } };