From 207e715059d2fde9df24e16b87f2510fb33f3859 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Mar 2001 22:06:53 +0000 Subject: addprinter and adddriver are working now :-) (This used to be commit 0cb7639cef4a1ba0d56d7e58bd7e03343cbf229d) --- source3/rpcclient/cmd_samr.c | 37 +++-- source3/rpcclient/cmd_spoolss.c | 312 +++++++++++++++++++++++++++++++++++++--- source3/rpcclient/rpcclient.c | 171 +++++++++++++++++----- 3 files changed, 459 insertions(+), 61 deletions(-) (limited to 'source3/rpcclient') diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 3772714cda..908245f5dc 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -25,7 +25,6 @@ #include "includes.h" -extern pstring server; extern DOM_SID domain_sid; /**************************************************************************** @@ -108,6 +107,7 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) got_user_pol = False; SAM_USERINFO_CTR user_ctr; SAM_USER_INFO_21 info_21; + fstring server; if (argc != 1) { printf("Usage: %s\n", argv[0]); @@ -120,6 +120,9 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) return NT_STATUS_UNSUCCESSFUL; } + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { @@ -223,6 +226,7 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) BOOL got_connect_pol = False, got_domain_pol = False, got_group_pol = False; GROUP_INFO_CTR group_ctr; + fstring server; if (argc != 1) { printf("Usage: %s\n", argv[0]); @@ -235,6 +239,9 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) return NT_STATUS_UNSUCCESSFUL; } + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { @@ -286,13 +293,18 @@ done: static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **argv) { - POLICY_HND connect_pol, domain_pol, user_pol; - uint32 result = NT_STATUS_UNSUCCESSFUL; - BOOL got_connect_pol = False, got_domain_pol = False, - got_user_pol = False; - uint32 num_groups, user_rid; - DOM_GID *user_gids; - int i; + POLICY_HND connect_pol, + domain_pol, + user_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + BOOL got_connect_pol = False, + got_domain_pol = False, + got_user_pol = False; + uint32 num_groups, + user_rid; + DOM_GID *user_gids; + int i; + fstring server; if (argc != 2) { printf("Usage: %s rid/name\n", argv[0]); @@ -306,7 +318,10 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char ** fprintf (stderr, "Could not initialize samr pipe!\n"); return NT_STATUS_UNSUCCESSFUL; } - + + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { @@ -366,6 +381,7 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar got_group_pol = False; uint32 num_members, *group_rids, *group_attrs, group_rid; int i; + fstring server; if (argc != 2) { printf("Usage: %s rid/name\n", argv[0]); @@ -380,6 +396,9 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar return NT_STATUS_UNSUCCESSFUL; } + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index b1160f1822..99a51eb338 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -32,21 +32,50 @@ extern pstring global_myname; extern pstring username, password; extern pstring workgroup; -struct table { - char *long_archi; - char *short_archi; +struct table_node { + char *long_archi; + char *short_archi; + int version; }; -struct table archi_table[]= { - - {"Windows 4.0", "WIN40" }, - {"Windows NT x86", "W32X86" }, - {"Windows NT R4000", "W32MIPS" }, - {"Windows NT Alpha_AXP", "W32ALPHA" }, - {"Windows NT PowerPC", "W32PPC" }, - {NULL, "" } +struct table_node archi_table[]= { + + {"Windows 4.0", "WIN40", 0 }, + {"Windows NT x86", "W32X86", 2 }, + {"Windows NT R4000", "W32MIPS", 2 }, + {"Windows NT Alpha_AXP", "W32ALPHA", 2 }, + {"Windows NT PowerPC", "W32PPC", 2 }, + {NULL, "", -1 } }; +/**************************************************************************** +function to do the mapping between the long architecture name and +the short one. +****************************************************************************/ +BOOL get_short_archi(char *short_archi, char *long_archi) +{ + int i=-1; + + DEBUG(107,("Getting architecture dependant directory\n")); + do { + i++; + } while ( (archi_table[i].long_archi!=NULL ) && + StrCaseCmp(long_archi, archi_table[i].long_archi) ); + + if (archi_table[i].long_archi==NULL) { + DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi)); + return FALSE; + } + + StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi)); + + DEBUGADD(108,("index: [%d]\n", i)); + DEBUGADD(108,("long architecture: [%s]\n", long_archi)); + DEBUGADD(108,("short architecture: [%s]\n", short_archi)); + + return True; +} + /********************************************************************** * dummy function -- placeholder @@ -164,11 +193,11 @@ printer info level 0 display function ****************************************************************************/ static void display_print_info_0(PRINTER_INFO_0 *i1) { - fstring name; - fstring the_server; + 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); + unistr_to_ascii(the_server, i1->servername.buffer, sizeof(the_server) - 1); printf("\tprintername:[%s]\n", name); printf("\tservername:[%s]\n", the_server); @@ -455,7 +484,8 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg BOOL opened_hnd = False; PRINTER_INFO_CTR ctr; fstring printername, - servername; + servername, + username; if (argc == 1 || argc > 3) { printf("Usage: %s printername [level]\n", argv[0]); @@ -473,9 +503,10 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg info_level = atoi(argv[2]); } - slprintf (printername, sizeof(fstring), "\\\\%s\\%s", server, argv[1]); slprintf (servername, sizeof(fstring), "\\\\%s", cli->desthost); strupper (servername); + slprintf (printername, sizeof(fstring), "\\\\%s\\%s", servername, argv[1]); + fstrcpy (username, cli->user_name); /* get a printer handle */ if ((result = cli_spoolss_open_printer_ex( @@ -483,7 +514,7 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg username, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; } - + opened_hnd = True; /* Get printer info */ @@ -833,7 +864,7 @@ static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1) } /*********************************************************************** - * Get printer information + * Get printer driver directory information */ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **argv) { @@ -877,13 +908,254 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a } +/******************************************************************************* + set the version and environment fields of a DRIVER_INFO_3 struct + ******************************************************************************/ +void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) +{ + + int i; + + for (i=0; archi_table[i].long_archi != NULL; i++) + { + if (strcmp(arch, archi_table[i].short_archi) == 0) + { + info->version = archi_table[i].version; + init_unistr (&info->architecture, archi_table[i].long_archi); + break; + } + } + + if (archi_table[i].long_archi == NULL) + { + DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch)); + } + + return; +} + + +/************************************************************************** + wrapper for strtok to get the next parameter from a delimited list. + Needed to handle the empty parameter string denoted by "NULL" + *************************************************************************/ +static char* get_driver_3_param (char* str, char* delim, UNISTR* dest) +{ + char *ptr; + + /* get the next token */ + ptr = strtok(str, delim); + + /* a string of 'NULL' is used to represent an empty + parameter because two consecutive delimiters + will not return an empty string. See man strtok(3) + for details */ + if (StrCaseCmp(ptr, "NULL") == 0) + ptr = NULL; + + if (dest != NULL) + init_unistr(dest, ptr); + + return ptr; +} + +/******************************************************************************** + fill in the members of a DRIVER_INFO_3 struct using a character + string in the form of + :::\ + :::\ + : + *******************************************************************************/ +static BOOL init_drv_info_3_members (DRIVER_INFO_3 *info, char *args) +{ + char *str, *str2; + uint32 len, i; + + /* fill in the UNISTR fields */ + str = get_driver_3_param (args, ":", &info->name); + str = get_driver_3_param (NULL, ":", &info->driverpath); + str = get_driver_3_param (NULL, ":", &info->datafile); + str = get_driver_3_param (NULL, ":", &info->configfile); + str = get_driver_3_param (NULL, ":", &info->helpfile); + str = get_driver_3_param (NULL, ":", &info->monitorname); + str = get_driver_3_param (NULL, ":", &info->defaultdatatype); + + /* */ + str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */ + str = str2; + + /* begin to strip out each filename */ + str = strtok(str, ","); + len = 0; + while (str != NULL) + { + /* keep a cumlative count of the str lengths */ + len += strlen(str)+1; + str = strtok(NULL, ","); + } + + /* allocate the space; add one extra slot for a terminating NULL. + Each filename is NULL terminated and the end contains a double + NULL */ + if ((info->dependentfiles=(uint16*)malloc((len+1)*sizeof(uint16))) == NULL) + { + DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n")); + return False; + } + for (i=0; idependentfiles[i] = (uint16)str2[i]; + } + info->dependentfiles[len] = '\0'; + + return True; +} + + +static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, char **argv) +{ + uint32 result, + level = 3; + PRINTER_DRIVER_CTR ctr; + DRIVER_INFO_3 info3; + fstring arch; + fstring driver_name; + + /* parse the command arguements */ + if (argc != 3) + { + printf ("Usage: %s \\\n", argv[0]); + printf ("\t:::\\\n"); + printf ("\t:::\\\n"); + printf ("\t:\n"); + + return NT_STATUS_NOPROBLEMO; + } + + /* Initialise RPC connection */ + if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) + { + fprintf (stderr, "Could not initialize spoolss pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + + /* Fill in the DRIVER_INFO_3 struct */ + ZERO_STRUCT(info3); + if (!get_short_archi(arch, argv[1])) + { + printf ("Error Unknown architechture [%s]\n", argv[1]); + return NT_STATUS_INVALID_PARAMETER; + } + else + set_drv_info_3_env(&info3, arch); + + if (!init_drv_info_3_members(&info3, argv[2])) + { + printf ("Error Invalid parameter list - %s.\n", argv[2]); + return NT_STATUS_INVALID_PARAMETER; + } + + + /* Get the directory. Only use Info level 1 */ + ctr.info3 = &info3; + if ((result = cli_spoolss_addprinterdriver (cli, level, &ctr)) + != NT_STATUS_NO_PROBLEMO) + { + return result; + } + + unistr_to_ascii (driver_name, info3.name.buffer, sizeof(driver_name)-1); + printf ("Printer Driver %s successfully installed.\n", driver_name); + + /* cleanup */ + cli_nt_session_close (cli); + + return result; + +} + + +static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char **argv) +{ + uint32 result, + level = 2; + PRINTER_INFO_CTR ctr; + PRINTER_INFO_2 info2; + fstring server; + + /* parse the command arguements */ + if (argc != 5) + { + printf ("Usage: %s \n", argv[0]); + return NT_STATUS_NOPROBLEMO; + } + + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + + /* Initialise RPC connection */ + if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) + { + fprintf (stderr, "Could not initialize spoolss pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + + /* Fill in the DRIVER_INFO_3 struct */ + ZERO_STRUCT(info2); +#if 0 /* JERRY */ + init_unistr( &info2.servername, server); +#endif + init_unistr( &info2.printername, argv[1]); + init_unistr( &info2.sharename, argv[2]); + init_unistr( &info2.drivername, argv[3]); + init_unistr( &info2.portname, argv[4]); + init_unistr( &info2.comment, "Created by rpcclient"); + init_unistr( &info2.printprocessor, "winprint"); + init_unistr( &info2.datatype, "RAW"); + info2.devmode = NULL; + info2.secdesc = NULL; + info2.attributes = PRINTER_ATTRIBUTE_SHARED; + info2.priority = 0; + info2.defaultpriority = 0; + info2.starttime = 0; + info2.untiltime = 0; + + /* These three fields must not be used by AddPrinter() + as defined in the MS Platform SDK documentation.. + --jerry + info2.status = 0; + info2.cjobs = 0; + info2.averageppm = 0; + */ + + + + /* Get the directory. Only use Info level 1 */ + ctr.printers_2 = &info2; + if ((result = cli_spoolss_addprinterex (cli, level, &ctr)) + != NT_STATUS_NO_PROBLEMO) + { + return result; + } + + printf ("Printer %s successfully installed.\n", argv[1]); + + /* cleanup */ + cli_nt_session_close (cli); + + return result; + +} + /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { { "SPOOLSS", NULL, "" }, - { "adddriver", cmd_spoolss_not_implemented, "Add a print driver (*)" }, - { "addprinter", cmd_spoolss_not_implemented, "Add a printer (*)" }, + { "adddriver", cmd_spoolss_addprinterdriver, "Add a print driver" }, + { "addprinter", cmd_spoolss_addprinterex, "Add a printer" }, { "enumdata", cmd_spoolss_not_implemented, "Enumerate printer data (*)" }, { "enumjobs", cmd_spoolss_not_implemented, "Enumerate print jobs (*)" }, { "enumports", cmd_spoolss_enum_ports, "Enumerate printer ports" }, diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 1b434dd696..42d9d4e486 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -30,14 +30,105 @@ extern struct cmd_set lsarpc_commands[]; extern struct cmd_set samr_commands[]; extern struct cmd_set spoolss_commands[]; -pstring password; -pstring username; -pstring workgroup; -pstring server; - DOM_SID domain_sid; +/*********************************************************************** + * read in username/password credentials from a file + */ +static void read_authfile ( + char *filename, + char* username, + char* password, + char* domain +) +{ + FILE *auth; + fstring buf; + uint16 len = 0; + char *ptr, *val, *param; + + if ((auth=sys_fopen(filename, "r")) == NULL) + { + printf ("ERROR: Unable to open credentials file!\n"); + return; + } + + while (!feof(auth)) + { + /* get a line from the file */ + if (!fgets (buf, sizeof(buf), auth)) + continue; + + len = strlen(buf); + + /* skip empty lines */ + if ((len) && (buf[len-1]=='\n')) + { + buf[len-1] = '\0'; + len--; + } + if (len == 0) + continue; + + /* break up the line into parameter & value. + will need to eat a little whitespace possibly */ + param = buf; + if (!(ptr = strchr (buf, '='))) + continue; + val = ptr+1; + *ptr = '\0'; + + /* eat leading white space */ + while ((*val!='\0') && ((*val==' ') || (*val=='\t'))) + val++; + + if (strwicmp("password", param) == 0) + fstrcpy (password, val); + else if (strwicmp("username", param) == 0) + fstrcpy (username, val); + else if (strwicmp("domain", param) == 0) + fstrcpy (domain, val); + + memset(buf, 0, sizeof(buf)); + } + fclose(auth); + + return; +} + +static char* next_command ( + char** cmdstr +) +{ + static pstring command; + char *p; + + if (!cmdstr || !(*cmdstr)) + return NULL; + + p = strchr(*cmdstr, ';'); + if (p) + *p = '\0'; + pstrcpy(command, *cmdstr); + *cmdstr = p; + + return command; +} +static void get_username (char *username) +{ + if (getenv("USER")) + pstrcpy(username,getenv("USER")); + + if (*username == 0 && getenv("LOGNAME")) + pstrcpy(username,getenv("LOGNAME")); + + if (*username == 0) { + pstrcpy(username,"GUEST"); + } + + return; +} /* Fetch the SID for this domain */ void fetch_domain_sid(struct cli_state *cli) @@ -75,7 +166,7 @@ void fetch_domain_sid(struct cli_state *cli) return; error: - fprintf(stderr, "could not obtain sid for domain %s\n", workgroup); + fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain); if (result != NT_STATUS_NOPROBLEMO) { fprintf(stderr, "error: %s\n", get_nt_error_msg(result)); @@ -87,7 +178,7 @@ void fetch_domain_sid(struct cli_state *cli) /* Initialise client credentials for authenticated pipe access */ void init_rpcclient_creds(struct ntuser_creds *creds, char* username, - char* workgroup, char* password) + char* domain, char* password) { ZERO_STRUCTP(creds); @@ -98,7 +189,7 @@ void init_rpcclient_creds(struct ntuser_creds *creds, char* username, } fstrcpy(creds->user_name, username); - fstrcpy(creds->domain, workgroup); + fstrcpy(creds->domain, domain); } /* List to hold groups of commands */ @@ -327,6 +418,7 @@ static void usage(char *pname) { printf("Usage: %s server [options]\n", pname); + printf("\t-A authfile file containing user credentials\n"); printf("\t-c \"command string\" execute semicolon separated cmds\n"); printf("\t-d debuglevel set the debuglevel\n"); printf("\t-l logfile name of logfile to use as opposed to stdout\n"); @@ -334,7 +426,7 @@ static void usage(char *pname) printf("\t-N don't ask for a password\n"); printf("\t-s configfile specify an alternative config file\n"); printf("\t-U username set the network username\n"); - printf("\t-W workgroup set the workgroup name\n"); + printf("\t-W domain set the domain name for user account\n"); printf("\n"); } @@ -342,19 +434,25 @@ static void usage(char *pname) int main(int argc, char *argv[]) { - extern char *optarg; - extern int optind; - struct in_addr dest_ip; - extern pstring global_myname; - BOOL got_pass = False; - BOOL interactive = True; - BOOL have_ip = False; - int opt; - int olddebug; - pstring cmdstr = "", servicesf = CONFIGFILE; + extern char *optarg; + extern int optind; + struct in_addr dest_ip; + extern pstring global_myname; + BOOL got_pass = False; + BOOL interactive = True; + BOOL have_ip = False; + int opt; + int olddebug; + pstring cmdstr = "", + servicesf = CONFIGFILE; struct ntuser_creds creds; struct cli_state cli; + fstring password, + username, + domain, + server; + charset_initialise(); setlinebuf(stdout); #ifdef HAVE_LIBREADLINE @@ -375,11 +473,17 @@ static void usage(char *pname) argv++; argc--; - while ((opt = getopt(argc, argv, "s:Nd:I:U:W:c:l:")) != EOF) { + while ((opt = getopt(argc, argv, "A:s:Nd:I:U:W:c:l:")) != EOF) { switch (opt) { + case 'A': + /* only get the username, password, and domain from the file */ + read_authfile (optarg, username, password, domain); + if (strlen (password)) + got_pass = True; + break; + case 'c': pstrcpy(cmdstr, optarg); - got_pass = True; break; case 'd': @@ -417,7 +521,7 @@ static void usage(char *pname) } case 'W': - pstrcpy(workgroup, optarg); + pstrcpy(domain, optarg); break; case 'h': @@ -432,13 +536,10 @@ static void usage(char *pname) setup_logging (argv[0], interactive); if (!interactive) reopen_logs(); - - charset_initialise(); + /* Load smb.conf file */ /* FIXME! How to get this DEBUGLEVEL to last over lp_load()? */ olddebug = DEBUGLEVEL; - - /* Load smb.conf file */ if (!lp_load(servicesf,True,False,False)) { fprintf(stderr, "Can't load %s\n", servicesf); } @@ -456,12 +557,15 @@ static void usage(char *pname) * initialize the credentials struct. Get password * from stdin if necessary */ + if (!strlen(username)) + get_username (username); + if (!got_pass) { - init_rpcclient_creds (&creds, username, workgroup, ""); + init_rpcclient_creds (&creds, username, domain, ""); pwd_read(&creds.pwd, "Enter Password: ", lp_encrypted_passwords()); } else { - init_rpcclient_creds (&creds, username, workgroup, password); + init_rpcclient_creds (&creds, username, domain, password); } memset(password,'X',strlen(password)); @@ -478,21 +582,24 @@ static void usage(char *pname) /* Load command lists */ add_command_set(rpcclient_commands); add_command_set(separator_command); + add_command_set(spoolss_commands); add_command_set(separator_command); + add_command_set(lsarpc_commands); add_command_set(separator_command); + add_command_set(samr_commands); add_command_set(separator_command); /* Do anything specified with -c */ if (cmdstr[0]) { - pstring cmd; - char *p = cmdstr; - uint32 result; + char *cmd; + char *p = cmdstr; + uint32 result; - while(next_token(&p, cmd, ";", sizeof(pstring))) { + while((cmd=next_command(&p)) != NULL) { result = process_cmd(&cli, cmd); } -- cgit