All changes related to rpcclient...
authorGerald Carter <jerry@samba.org>
Tue, 8 Aug 2000 06:57:48 +0000 (06:57 +0000)
committerGerald Carter <jerry@samba.org>
Tue, 8 Aug 2000 06:57:48 +0000 (06:57 +0000)
- cleaned up some code
- Fixed a few memory leaks of my own making
- Add AddPrinterDriver(); I'm missing some of the semantics
  here as the call is done correctly, but I'm not getting all
  the information right in the DRIVER_INFO_3 struct I think.
  Will work on it tomorrow some more...

--jerry
(This used to be commit 3bf9a29f34ee4ade5180c5a0b0b9ff4aca7f0f08)

source3/include/rpc_misc.h
source3/include/rpc_spoolss.h
source3/lib/msrpc-client.c
source3/rpc_client/cli_connect.c
source3/rpc_client/cli_spoolss.c
source3/rpc_parse/parse_spoolss.c
source3/rpcclient/cmd_spoolss.c

index 6fb2d63ed48ed62362a42fbaf39f11c2aeba12fd..d3e56634a934743e8957ccebd1d83c4503719ea3 100644 (file)
@@ -306,7 +306,6 @@ typedef struct _cli_auth_fns cli_auth_fns;
 struct user_creds;
 struct cli_connection {
 
-        uint32                  num_connections;
         char                    *srv_name;
         char                    *pipe_name;
         struct user_creds       usr_creds;
index bf854492affa237ea75c3be0067fbe93472aa66b..ead4c6cbc143622c08a95f36b5c39babdf648cd8 100755 (executable)
@@ -889,11 +889,34 @@ typedef struct driver_info_3
 }
 DRIVER_INFO_3;
 
+typedef struct driver_info_6
+{
+       uint32 version;
+       UNISTR name;
+       UNISTR architecture;
+       UNISTR driverpath;
+       UNISTR datafile;
+       UNISTR configfile;
+       UNISTR helpfile;
+       uint16 *dependentfiles;
+       UNISTR monitorname;
+       UNISTR defaultdatatype;
+       uint16* previousdrivernames;
+       NTTIME driver_date;
+       uint32 driver_version;
+       UNISTR mfgname;
+       UNISTR oem_url;
+       UNISTR hardware_id;
+       UNISTR provider;
+}
+DRIVER_INFO_6;
+
 typedef struct driver_info_info
 {
        DRIVER_INFO_1 *info1;
        DRIVER_INFO_2 *info2;
        DRIVER_INFO_3 *info3;
+       DRIVER_INFO_6 *info6;
 }
 PRINTER_DRIVER_CTR;
 
index ee3ee0adcc7ee4b21866bb17f575bbdbc6655521..867094a2c6007f385d2b152a8baae7ccb2bc3fa5 100644 (file)
@@ -181,7 +181,7 @@ void msrpc_sockopt(struct msrpc_state *msrpc, char *options)
 
 
 static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
-                               const struct user_creds *usr)
+                              struct user_creds *usr)
 {
        struct msrpc_state msrpc_redir;
 
@@ -247,7 +247,7 @@ static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
 
 static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
                                const char* pipe_name,
-                               const struct user_creds *usr)
+                               struct user_creds *usr)
 {
        int sock;
        fstring path;
index 16279488e82cd7ff1f851394e283702e4742960d..6dcf92c57d5082926093b3c5ec4e059e29d8b9b7 100644 (file)
@@ -108,7 +108,7 @@ void free_connections(void)
 }
 
 static struct cli_connection *cli_con_get(const char *srv_name,
-                                          const char *pipe_name,
+                                          char *pipe_name,
                                           cli_auth_fns * auth,
                                           void *auth_creds, BOOL reuse)
 {
index 21e87b579997307c410299048f6308d0a718de09..1bfdf6a4685e4112cd5c087e431e2e503e5773df 100644 (file)
@@ -613,6 +613,7 @@ BOOL spoolss_addprinterex(POLICY_HND *hnd, const char* srv_name, PRINTER_INFO_2
 
         prs_mem_free(&rbuf);
         prs_mem_free(&buf );
+       free_spoolss_q_addprinterex(&q_o);
 
        if (mem_ctx)
                talloc_destroy(mem_ctx);
@@ -804,4 +805,55 @@ uint32 spoolss_getprinterdriverdir(fstring srv_name, fstring env_name, uint32 le
         return r_o.status;
 }
 
+/******************************************************************************
+ AddPrinterDriver()
+ *****************************************************************************/
+uint32 spoolss_addprinterdriver(const char *srv_name, uint32 level, PRINTER_DRIVER_CTR *info)
+{
+        prs_struct                     rbuf;
+        prs_struct                     buf;
+        SPOOL_Q_ADDPRINTERDRIVER       q_o;
+        SPOOL_R_ADDPRINTERDRIVER       r_o;
+       TALLOC_CTX                      *mem_ctx = NULL;
+       struct cli_connection           *con = NULL;
+       
+        if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+                return False;
+
+       if ((mem_ctx=talloc_init()) == NULL)
+       {
+               DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+               return False;
+       }
+        prs_init(&buf , MAX_PDU_FRAG_LEN, 4, mem_ctx, MARSHALL);
+        prs_init(&rbuf, 0, 4, mem_ctx, UNMARSHALL);
+       
+       /* make the ADDPRINTERDRIVER PDU */
+       make_spoolss_q_addprinterdriver(&q_o, srv_name, level, info);
+
+       /* turn the data into an io stream */
+        if (spoolss_io_q_addprinterdriver("", &q_o, &buf, 0) &&
+           rpc_con_pipe_req(con, SPOOLSS_ADDPRINTERDRIVER, &buf, &rbuf)) 
+       {
+               ZERO_STRUCT(r_o);
+
+               if(!spoolss_io_r_addprinterdriver("", &r_o, &rbuf, 0)) 
+               {
+                        /* report error code */
+                        DEBUG(5,("SPOOLSS_ADDPRINTEREX: %s\n", get_nt_error_msg(r_o.status)));
+               }
+        }
+
+
+        prs_mem_free(&rbuf);
+        prs_mem_free(&buf );
+       free_spool_driver_info_3(q_o.info.info_3);
+
+       if (mem_ctx)
+               talloc_destroy(mem_ctx);
+               
+       return r_o.status;
+
+}
+
 
index 033b680e645d26bdc427b6442b8114cf58596d5c..8ebdd55473d09dbe6aa33ce26261935e217a8050 100644 (file)
@@ -772,6 +772,41 @@ BOOL make_spoolss_q_addprinterex(SPOOL_Q_ADDPRINTEREX *q_u, const char *srv_name
        
        return True;
 }
+
+/*******************************************************************
+ free dynamically allocated members
+ ********************************************************************/
+void free_spoolss_q_addprinterex(SPOOL_Q_ADDPRINTEREX *q_u)
+{
+       switch (q_u->info.level)
+       {
+       case 1:
+               if (q_u->info.info_1 != NULL)
+               {
+                       free(q_u->info.info_1);
+                       q_u->info.info_1 = NULL;
+               }
+                       break;
+       case 2:
+               if (q_u->info.info_2 != NULL)
+               {
+                       free(q_u->info.info_2);
+                       q_u->info.info_2 = NULL;
+               }
+               break;
+       case 3:
+               if (q_u->info.info_3 != NULL)
+               {
+                       free(q_u->info.info_3);
+                       q_u->info.info_3 = NULL;
+               }
+               break;
+       }
+
+       return;
+       
+}
+       
 /*******************************************************************
 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
 *******************************************************************/
@@ -898,8 +933,7 @@ BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_
  ********************************************************************/
 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
                                 const POLICY_HND *handle,
-                                const UNISTR2 *valuename,
-                                uint32 size)
+                                UNISTR2 *valuename, uint32 size)
 {
         if (q_u == NULL) return False;
 
@@ -4243,7 +4277,143 @@ void free_spool_printer_driver_info_level(SPOOL_PRINTER_DRIVER_INFO_LEVEL *il)
 }
 
 /*******************************************************************
-********************************************************************/  
+ init a SPOOL_Q_ADDPRINTERDRIVER struct
+ ******************************************************************/
+BOOL make_spoolss_q_addprinterdriver(SPOOL_Q_ADDPRINTERDRIVER *q_u, 
+                                    const char* srv_name, uint32 level, 
+                                    PRINTER_DRIVER_CTR *info)
+{
+       DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
+       
+       q_u->server_name_ptr = (srv_name!=NULL)?1:0;
+       init_unistr2(&q_u->server_name, srv_name, strlen(srv_name)+1);
+       
+       q_u->level = level;
+       
+       q_u->info.level = level;
+       q_u->info.ptr = (info!=NULL)?1:0;
+       switch (level)
+       {
+               /* info level 3 is supported by Windows 95/98, 
+                  WinNT and Win2k */
+               case 3 :
+                       q_u->info.info_3=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3*)
+                                         malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
+                       make_spool_driver_info_3(q_u->info.info_3, info->info3);
+                       break;
+               
+               /* info level 6 is supported by WinME and Win2k */
+               case 6:
+                       /* WRITEME!!  will add later  --jerry */
+                       break;
+               default:
+                       DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown \
+info level [%d]\n", level));
+                       break;
+       
+       }
+       
+       return True;
+}
+
+BOOL make_spool_driver_info_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *spool_drv_info,
+                             DRIVER_INFO_3 *info3)
+{
+       uint32          len = 0;
+       uint16          *ptr = info3->dependentfiles;
+       BOOL            done = False;
+       BOOL            null_char = False;
+
+       spool_drv_info->cversion        = info3->version;
+       spool_drv_info->name_ptr        = (info3->name.buffer!=NULL)?1:0;
+       spool_drv_info->environment_ptr = (info3->architecture.buffer!=NULL)?1:0;
+       spool_drv_info->driverpath_ptr  = (info3->driverpath.buffer!=NULL)?1:0;
+       spool_drv_info->datafile_ptr    = (info3->datafile.buffer!=NULL)?1:0;
+       spool_drv_info->configfile_ptr  = (info3->configfile.buffer!=NULL)?1:0;
+       spool_drv_info->helpfile_ptr    = (info3->helpfile.buffer!=NULL)?1:0;
+       spool_drv_info->monitorname_ptr = (info3->monitorname.buffer!=NULL)?1:0;
+       spool_drv_info->defaultdatatype_ptr     = (info3->defaultdatatype.buffer!=NULL)?1:0;
+
+       init_unistr2_from_unistr(&spool_drv_info->name, &info3->name);
+       init_unistr2_from_unistr(&spool_drv_info->environment, &info3->architecture);
+       init_unistr2_from_unistr(&spool_drv_info->driverpath, &info3->driverpath);
+       init_unistr2_from_unistr(&spool_drv_info->datafile, &info3->datafile);
+       init_unistr2_from_unistr(&spool_drv_info->configfile, &info3->configfile);
+       init_unistr2_from_unistr(&spool_drv_info->helpfile, &info3->helpfile);
+       init_unistr2_from_unistr(&spool_drv_info->monitorname, &info3->monitorname);
+       init_unistr2_from_unistr(&spool_drv_info->defaultdatatype, &info3->defaultdatatype);
+
+       while (!done)
+       {
+               switch (*ptr)
+               {
+                       case 0:
+                               /* the null_char BOOL is used to help locate
+                                  two '\0's back to back */
+                               if (null_char)
+                                       done = True;
+                               else
+                                       null_char = True;
+                               break;
+                                       
+                       default:
+                               null_char = False;
+                               ;;
+                               break;                          
+               }
+               len++;
+               ptr++;
+       }
+       spool_drv_info->dependentfiles_ptr = (info3->dependentfiles!=NULL)?1:0;
+       spool_drv_info->dependentfilessize = len;
+       make_spool_buffer5(&spool_drv_info->dependentfiles, len, info3->dependentfiles);
+       
+       return True;
+}           
+
+void free_spool_driver_info_3 (SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info)
+{
+       if (info != NULL)
+       {
+               free_spool_buffer5(&info->dependentfiles);
+       }
+       
+       return;
+}
+
+/*******************************************************************
+ make a BUFFER5 struct from a uint16*
+ ******************************************************************/
+BOOL make_spool_buffer5(BUFFER5 *buf5, uint32 len, uint16 *src)
+{
+
+       buf5->buf_len = len;
+       if((buf5->buffer=(uint16*)malloc(sizeof(uint16)*len)) == NULL)
+       {
+               DEBUG(0,("make_spool_buffer5: Unable to malloc memory for buffer!\n"));
+               return False;
+       }
+       
+       memcpy(buf5->buffer, src, sizeof(uint16)*len);
+
+       return True;
+}
+
+
+void free_spool_buffer5(BUFFER5 *buf)
+{
+       if (buf != NULL)
+       {
+               free(buf->buffer);
+               buf->buffer = NULL;
+       }
+       
+       return;
+}
+
+/*******************************************************************
+ fill in the prs_struct for a ADDPRINTERDRIVER request PDU
+ ********************************************************************/  
 BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
 {
        prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
@@ -4855,6 +5025,7 @@ BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_st
        return True;
 }
 
+
 /*******************************************************************
 ********************************************************************/  
 BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
index f79a7042d2ec6a84268b2f37bb32601f936ff223..35e09c76e13cb1fc425545d9f5679b88ba0b0b7f 100644 (file)
@@ -36,6 +36,49 @@ extern FILE* out_hnd;
 
 extern struct user_creds *usr_creds;
 
+/****************************************************************************
+function to do the mapping between the long architecture name and
+the short one.
+****************************************************************************/
+static BOOL get_short_archi(char *short_archi, char *long_archi)
+{
+        struct table {
+                char *long_archi;
+                char *short_archi;
+        };
+
+        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,                   ""         }
+        };
+
+        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(107,("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;
+}
+
 /****************************************************************************
 nt spoolss query
 ****************************************************************************/
@@ -520,7 +563,7 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
        /* check (and copy) the command line arguments */
         if (argc < 3) {
                 report(out_hnd, "spooladdprinterex <name> <driver> <port>\n");
-                return NT_STATUS_NOPROBLEMO;
+                return NT_STATUS_INVALID_PARAMETER;
         }
        else
        {
@@ -559,7 +602,6 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
                        report (out_hnd, "cmd_spoolss_addprinterex: FAILED to enumerate ports\n");
                        return NT_STATUS_NOPROBLEMO;
                }
-                                       
        }
        
        /*
@@ -584,7 +626,6 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
                return NT_STATUS_NOPROBLEMO;
        }
        
-        
        /*
         * Need to build the PRINTER_INFO_2 struct here.
         * I think it would be better only to deal with a PRINTER_INFO_2
@@ -641,6 +682,196 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
 ********************************************************************************/
 uint32 cmd_spoolss_addprinterdriver(struct client_info *info, int argc, char *argv[])
 {
+       PRINTER_DRIVER_CTR      driver_info;
+       DRIVER_INFO_3           info3;
+       fstring                 arch;
+        fstring                srv_name;
+       uint32                  result = NT_STATUS_NO_PROBLEMO;
+       
+       /* parse the command arguements */
+       if (argc < 2)
+       {
+               report (out_hnd, "spooladdprinterdriver <arch>\\\n");
+               report (out_hnd, "\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
+               report (out_hnd, "\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
+               report (out_hnd, "\t<Default Data Type>:<Comma Separated list of Files>\n");
 
-        return NT_STATUS_NOPROBLEMO;
+                return NT_STATUS_INVALID_PARAMETER;
+        }
+       else
+       {
+               ZERO_STRUCT(info3);
+               
+               /* get the enviorment for the driver */
+               if (!get_short_archi(arch, argv[1]))
+               {
+                       report (out_hnd, "Unknown architechture [%s]\n", argv[1]);
+                       return NT_STATUS_INVALID_PARAMETER;
+                       
+               }
+               else
+               {
+                       set_drv_info_3_env(&info3, arch);
+               }
+               
+               /* fill in the other struct members */
+               if (!init_drv_info_3_members(&info3, argv[2]))
+               {
+                       report (out_hnd, "Invalid parameter list.\n");
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+       }
+       
+       /* get the server name */
+        fstrcpy(srv_name, "\\\\");
+        fstrcat(srv_name, info->dest_host);
+        strupper(srv_name);
+       
+       /* call AddPrinterDriver() woth an info level 3 */
+       driver_info.info3 = &info3;
+       if ((result=spoolss_addprinterdriver(srv_name, 3, &driver_info)) != NT_STATUS_NO_PROBLEMO)
+       {
+               report( out_hnd, "spoolss_addprinterdriver: Add Printer failed [%d]\n",
+                       result);
+       }
+       
+       free_drv_info_3(&info3);
+       
+        return result;
 }      
+
+/*******************************************************************************
+ 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)
+{
+       if (strcmp(arch, "WIN40") == 0)
+       {
+               info->version = 0;
+               init_unistr(&info->architecture, "Windows 4.0");
+       }
+       else if (strcmp(arch, "W32X86") == 0)
+       {
+               info->version = 2;
+               init_unistr(&info->architecture, "Windows NT x86");
+       }
+       else if (strcmp(arch, "W32MIPS") == 0)
+       {
+               info->version = 2;
+               init_unistr(&info->architecture, "Windows NT R4000");
+       }
+       else if (strcmp(arch, "W32ALPHA") == 0)
+       {
+               info->version = 2;
+               init_unistr(&info->architecture, "Windows NT Alpha_AXP");
+       }
+       else if (strcmp(arch, "W32PPC") == 0)
+       {
+               info->version = 2;
+               init_unistr(&info->architecture, "Windows NT PowerPC");
+       }
+       else
+       {
+               DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
+       }
+       
+       return;
+}
+
+/********************************************************************************
+ fill in the members of a DRIVER_INFO_3 struct using a character 
+ string in the form of
+        <Long Printer Name>:<Driver File Name>:<Data File Name>:\
+            <Config File Name>:<Help File Name>:<Language Monitor Name>:\
+            <Default Data Type>:<Comma Separated list of Files> 
+ *******************************************************************************/
+BOOL init_drv_info_3_members (DRIVER_INFO_3 *info, char *args)
+{
+       char    *str, *str2;
+       uint32  len, i;
+       
+       /* <Long Printer Name> */
+       if ((str = strtok(args, ":")) == NULL)
+               return False;
+       else
+               init_unistr(&info->name, str);
+
+       /* <Driver File Name> */
+       if ((str = strtok(NULL, ":")) == NULL)
+               return False;
+       else
+               init_unistr(&info->driverpath, str);
+
+       /* <Data File Name > */
+       if ((str = strtok(NULL, ":")) == NULL)
+               return False;
+       else
+               init_unistr(&info->datafile, str);
+
+       /* <Config File Name> */
+       if ((str = strtok(NULL, ":")) == NULL)
+               return False;
+       else
+               init_unistr(&info->configfile, str);
+
+       /* <Help File Name> */
+       if ((str = strtok(NULL, ":")) == NULL)
+               return False;
+       else
+               init_unistr(&info->helpfile, str);
+
+       /* <Language Monitor Name> */
+       if ((str = strtok(NULL, ":")) == NULL)
+               return False;
+       else
+               init_unistr(&info->monitorname, str);
+
+       /* <Default Data Type> */
+       if ((str = strtok(NULL, ":")) == NULL)
+               return False;
+       else
+               init_unistr(&info->defaultdatatype, str);
+
+       /* <Comma Separated List of Dependent Files> */
+       str = strtok(NULL, ":");        /* get the list of dependent files */
+       str2 = str;                     /* save the beginning of the string */
+       str = strtok(str, ",");         /* begin to strip out each filename */
+       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; i<len; i++)
+       {
+               info->dependentfiles[i] = (uint16)str2[i];
+               info->dependentfiles[i] = info->dependentfiles[i] << 8;
+       }
+       info->dependentfiles[len+1] = '\0';
+
+       return True;
+}
+
+/*****************************************************************************
+ free any dynamically allocated members
+ ****************************************************************************/
+void free_drv_info_3 (DRIVER_INFO_3 *info)
+{
+       if (info->dependentfiles != NULL)
+       {
+               free(info->dependentfiles);
+               info->dependentfiles = NULL;
+       }
+       
+       return;
+}