More rpcclient merge issues:
authorGerald Carter <jerry@samba.org>
Fri, 7 Jul 2000 06:20:46 +0000 (06:20 +0000)
committerGerald Carter <jerry@samba.org>
Fri, 7 Jul 2000 06:20:46 +0000 (06:20 +0000)
        * fixes some readline bugs from the merge
        * first attempt at commands (spoolenum almost works)
        * no changes to existing functions in HEAD; only additions
          of new functions.  I'll weed out what I can as I go.

--jerry
(This used to be commit 61d2aad5dc2b212b11c981f1eca47efa627e9fc8)

16 files changed:
source3/include/ntdomain.h
source3/include/proto.h
source3/include/rpc_client_proto.h
source3/lib/cmd_interp.c
source3/lib/msrpc-client.c
source3/lib/util_unistr.c
source3/libsmb/cliconnect.c
source3/rpc_client/cli_connect.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_spoolss.c [new file with mode: 0644]
source3/rpc_client/cli_use.c
source3/rpc_client/msrpc_spoolss.c [new file with mode: 0644]
source3/rpc_client/ncacn_np_use.c
source3/rpc_client/ncalrpc_l_use.c
source3/rpc_parse/parse_creds.c
source3/rpc_parse/parse_prs.c

index 08c8163cda01faa0af72a3277c22dc506f84cccd..ebd24c9dd62fefff9e1e8599e2ce50df65e60294 100644 (file)
  * A bunch of stuff that was put into smb.h
  * in the NTDOM branch - it didn't belong there.
  */
+
+#define CHECK_STRUCT(data) \
+{ \
+        if ((data)->struct_start != 0xfefefefe || \
+            (data)->struct_end != 0xdcdcdcdc) \
+        { \
+                DEBUG(0,("uninitialised structure (%s, %d)\n", \
+                FUNCTION_MACRO, __LINE__)); \
+                sleep(30); \
+        } \
+}
+
  
 typedef struct _prs_struct 
 {
index 1b23ba1fbc7f053934c6c0d00b13c786e78dd1c8..8fcad544f425bebfbbd571e691e3314c08203f20 100644 (file)
@@ -43,6 +43,16 @@ void charset_initialise(void);
 void codepage_initialise(int client_codepage);
 void add_char_string(char *s);
 
+/*The following definitions come from  lib/cmd_interp.c  */
+
+void free_cmd_set_array(uint32 num_entries, struct command_set **entries);
+struct command_set *add_cmd_set_to_array(uint32 *len,
+                                        struct command_set ***array,
+                                        const struct command_set *cmd);
+void add_command_set(const struct command_set *cmds);
+void cmd_set_no_autoconnect(void);
+int command_main(int argc, char *argv[]);
+
 /*The following definitions come from  lib/crc32.c  */
 
 uint32 crc32_calc_buffer( char *buffer, uint32 count);
@@ -146,6 +156,8 @@ BOOL receive_msrpc(int fd, prs_struct *data, unsigned int timeout);
 BOOL msrpc_send(int fd, prs_struct *ps);
 BOOL msrpc_receive(int fd, prs_struct *ps);
 void ncalrpc_l_shutdown(struct msrpc_local *msrpc);
+struct msrpc_local *ncalrpc_l_initialise(struct msrpc_local *msrpc,
+                                         const vuser_key * key);
 BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name);
 void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_creds *usr);
 void msrpc_close_socket(struct msrpc_state *msrpc);
@@ -158,6 +170,8 @@ struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid);
 void msrpc_shutdown(struct msrpc_state *msrpc);
 BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
                const char *pipe_name);
+BOOL ncalrpc_l_establish_connection(struct msrpc_local *msrpc,
+                                    const char *pipe_name);
 
 /*The following definitions come from  lib/msrpc_use.c  */
 
@@ -514,6 +528,8 @@ char *skip_unibuf(char *src, size_t len);
 char *dos_unistrn2(uint16 *src, int len);
 char *dos_unistr2(uint16 *src);
 char *dos_unistr2_to_str(UNISTR2 *str);
+void ascii_to_unistr(uint16 *dest, const char *src, int maxlen);
+void unistr_to_ascii(char *dest, const uint16 *src, int len);
 void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen);
 uint32 buffer2_to_uint32(BUFFER2 *str);
 char *dos_buffer2_to_str(BUFFER2 *str);
@@ -1712,6 +1728,16 @@ BOOL profile_setup(BOOL rdonly);
 void init_connections(void);
 void free_connections(void);
 void cli_connection_free(struct cli_connection *con);
+void cli_connection_unlink(struct cli_connection *con);
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+                         struct cli_connection **con);
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+                              struct cli_connection **con,
+                              cli_auth_fns * auth, void *auth_creds);
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con);
+void *cli_conn_get_auth_creds(struct cli_connection *con);
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+                      prs_struct * data, prs_struct * rdata);
 
 /*The following definitions come from  rpc_client/cli_login.c  */
 
@@ -1759,6 +1785,7 @@ BOOL change_trust_account_password( char *domain, char *remote_machine_list);
 
 BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                       prs_struct *data, prs_struct *rdata);
+BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name);
 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name);
 void cli_nt_session_close(struct cli_state *cli);
@@ -1847,6 +1874,12 @@ BOOL do_samr_query_userinfo(struct cli_state *cli,
 BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd);
 #endif
 
+/*The following definitions come from  rpc_client/cli_spoolss.c  */
+
+uint32 spoolss_enum_printers(uint32 flags, fstring srv_name, uint32 level,
+                             NEW_BUFFER *buffer, uint32 offered,
+                             uint32 *needed, uint32 *returned);
+
 /*The following definitions come from  rpc_client/cli_srvsvc.c  */
 
 BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
@@ -1890,14 +1923,28 @@ BOOL do_wks_query_info(struct cli_state *cli,
                        char *server_name, uint32 switch_value,
                        WKS_INFO_100 *wks100);
 
+/*The following definitions come from  rpc_client/msrpc_spoolss.c  */
+
+BOOL msrpc_spoolss_enum_printers(char* srv_name, uint32 flags, uint32 level, PRINTER_INFO_CTR ctr);
+
 /*The following definitions come from  rpc_client/ncacn_np_use.c  */
 
 BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
                       const vuser_key * key,
                       BOOL force_close, BOOL *connection_closed);
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+                                     const vuser_key * key);
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+                                  const vuser_key * key,
+                                  const char *srv_name,
+                                  const struct ntuser_creds *ntc,
+                                  BOOL reuse, BOOL *is_new_connection);
 
 /*The following definitions come from  rpc_client/ncalrpc_l_use.c  */
 
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+                                      const vuser_key * key,
+                                      BOOL reuse, BOOL *is_new);
 BOOL ncalrpc_l_use_del(const char *pipe_name,
                        const vuser_key * key,
                        BOOL force_close, BOOL *connection_closed);
@@ -1925,6 +1972,7 @@ BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth);
 void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from);
 void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from);
 void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from);
+void create_ntc_from_cli_state (CREDS_NT *to, const struct cli_state *cli_from);
 void copy_nt_creds(struct ntuser_creds *to,
                                const struct ntuser_creds *from);
 void copy_user_creds(struct user_creds *to,
@@ -2202,6 +2250,9 @@ BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
 BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
 BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
                                uint32 ptr_uint32, uint32 data_size);
+void prs_free_data(prs_struct *buf);
+BOOL prs_realloc_data(prs_struct *buf, size_t new_size);
+char *prs_data(const prs_struct *buf, uint32 offset);
 int tdb_prs_store(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps);
 int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps);
 
@@ -3037,6 +3088,45 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid);
 BOOL api_wkssvc_rpc(pipes_struct *p);
 #endif
 
+/*The following definitions come from  rpcclient/cmd_spoolss.c  */
+
+uint32 cmd_spoolss_enum_printers(struct client_info *info, int argc, char *argv[]);
+
+/*The following definitions come from  rpcclient/display_sec.c  */
+
+void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *const sec);
+
+/*The following definitions come from  rpcclient/display_spool.c  */
+
+void display_printer_info_ctr(FILE *out_hnd, enum action_type action, uint32 level,
+                               uint32 count, PRINTER_INFO_CTR ctr);
+void display_printer_enumdata(FILE *out_hnd, enum action_type action, uint32 idx, 
+                               uint32 valuelen, uint16 *value, uint32 rvaluelen,
+                               uint32 type, 
+                               uint32 datalen, uint8 *data, uint32 rdatalen);
+void display_job_info_2(FILE *out_hnd, enum action_type action, 
+               JOB_INFO_2 *const i2);
+void display_job_info_1(FILE *out_hnd, enum action_type action, 
+               JOB_INFO_1 *const i1);
+void display_job_info_2_ctr(FILE *out_hnd, enum action_type action, 
+                               uint32 count, JOB_INFO_2 *const *const ctr);
+void display_job_info_1_ctr(FILE *out_hnd, enum action_type action, 
+                               uint32 count, JOB_INFO_1 *const *const ctr);
+void display_job_info_ctr(FILE *out_hnd, enum action_type action, 
+                               uint32 level, uint32 count,
+                               void *const *const ctr);
+void display_printer_driver_ctr(FILE *out_hnd, enum action_type action, uint32 level,
+                               uint32 count, PRINTER_DRIVER_CTR ctr);
+void display_printerdriverdir_info_ctr(FILE *out_hnd, enum action_type action, uint32 level,
+                               DRIVER_DIRECTORY_CTR ctr);
+
+/*The following definitions come from  rpcclient/rpcclient.c  */
+
+
+/*The following definitions come from  rpcclient/spoolss_cmds.c  */
+
+void add_spl_commands(void);
+
 /*The following definitions come from  smbd/blocking.c  */
 
 #if OLD_NTDOMAIN
index 76820574397f2485e1f364ea636bad9db43579f5..e3ef439804781f0e6a6c30c5be82e21074829acc 100644 (file)
@@ -8,6 +8,16 @@
 void init_connections(void);
 void free_connections(void);
 void cli_connection_free(struct cli_connection *con);
+void cli_connection_unlink(struct cli_connection *con);
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+                         struct cli_connection **con);
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+                              struct cli_connection **con,
+                              cli_auth_fns * auth, void *auth_creds);
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con);
+void *cli_conn_get_auth_creds(struct cli_connection *con);
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+                      prs_struct * data, prs_struct * rdata);
 
 /*The following definitions come from  rpc_client/cli_login.c  */
 
@@ -55,6 +65,7 @@ BOOL change_trust_account_password( char *domain, char *remote_machine_list);
 
 BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                       prs_struct *data, prs_struct *rdata);
+BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name);
 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name);
 void cli_nt_session_close(struct cli_state *cli);
@@ -143,6 +154,12 @@ BOOL do_samr_query_userinfo(struct cli_state *cli,
 BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd);
 #endif
 
+/*The following definitions come from  rpc_client/cli_spoolss.c  */
+
+uint32 spoolss_enum_printers(uint32 flags, fstring srv_name, uint32 level,
+                             NEW_BUFFER *buffer, uint32 offered,
+                             uint32 *needed, uint32 *returned);
+
 /*The following definitions come from  rpc_client/cli_srvsvc.c  */
 
 BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
@@ -191,9 +208,19 @@ BOOL do_wks_query_info(struct cli_state *cli,
 BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
                       const vuser_key * key,
                       BOOL force_close, BOOL *connection_closed);
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+                                     const vuser_key * key);
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+                                  const vuser_key * key,
+                                  const char *srv_name,
+                                  const struct ntuser_creds *ntc,
+                                  BOOL reuse, BOOL *is_new_connection);
 
 /*The following definitions come from  rpc_client/ncalrpc_l_use.c  */
 
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+                                      const vuser_key * key,
+                                      BOOL reuse, BOOL *is_new);
 BOOL ncalrpc_l_use_del(const char *pipe_name,
                        const vuser_key * key,
                        BOOL force_close, BOOL *connection_closed);
index 7b90daa06f39ac856b1389422710227458be0a56..f952a57e5787941d8e2df6837e90fa4795c98f41 100644 (file)
@@ -348,8 +348,9 @@ static uint32 do_command(struct client_info *info, char *line)
        {
                return False;
        }
-
-       if ((i = process_tok(cmd_argv[0])) >= 0)
+       
+       i = process_tok(cmd_argv[0]);
+       if (i >= 0)
        {
                int argc = ((int)cmd_argc)-1;
                char **argv = cmd_argv;
@@ -418,7 +419,7 @@ static uint32 process(struct client_info *info, char *cmd_str)
        {
                while (!feof(stdin))
                {
-#ifdef HAVE_READLINE
+#ifdef HAVE_LIBREADLINE
                        char *ret_line;
 #endif
                        pstring pline;
@@ -447,7 +448,7 @@ static uint32 process(struct client_info *info, char *cmd_str)
                                    sizeof(pline) - 1);
                        safe_strcat(pline, "]$ ", sizeof(pline) - 1);
 
-#ifndef HAVE_READLINE
+#ifndef HAVE_LIBREADLINE
 
                        /* display a prompt */
                        fprintf(out_hnd, "%s", CNV_LANG(pline));
@@ -461,7 +462,7 @@ static uint32 process(struct client_info *info, char *cmd_str)
                                break;
                        }
 
-#else /* HAVE_READLINE */
+#else /* HAVE_LIBREADLINE */
 
                        if (!(ret_line = readline(pline)))
                                break;
@@ -535,7 +536,7 @@ static void usage(char *pname)
        fprintf(out_hnd, "\n");
 }
 
-#ifdef HAVE_READLINE
+#ifdef HAVE_LIBREADLINE
 
 /****************************************************************************
 GNU readline completion functions
@@ -648,7 +649,7 @@ static char *complete_cmd_null(char *text, int state)
        return NULL;
 }
 
-#endif /* HAVE_READLINE */
+#endif /* HAVE_LIBREADLINE */
 
 static void set_user_password(struct ntuser_creds *u,
                              BOOL got_pass, char *password)
@@ -708,6 +709,7 @@ static uint32 cmd_use(struct client_info *info, int argc, char *argv[])
                report(out_hnd, "    -d     Deletes a connection\n");
                report(out_hnd, "    -f     Forcibly deletes a connection\n");
                report(out_hnd, "net -u     Shows all connections\n");
+               return 0;
        }
 
        if (argc > 1 && (*argv[1] != '-'))
@@ -1248,7 +1250,7 @@ static void read_user_env(struct ntuser_creds *u)
 
 static void readline_init(void)
 {
-#ifdef HAVE_READLINE
+#ifdef HAVE_LIBREADLINE
        /* Initialise GNU Readline */ rl_readline_name = "rpcclient";
        rl_attempted_completion_function = completion_fn;
        rl_completion_entry_function = (Function *) complete_cmd_null;
@@ -1260,7 +1262,7 @@ static void readline_init(void)
 #else
        int x;
        x = 0;                  /* stop compiler warnings */
-#endif /* HAVE_READLINE */
+#endif /* HAVE_LIBREADLINE */
 }
 
 /****************************************************************************
index 696413b4f9d40099da60a2c25099012a4558907b..9b9350cb7ed65e0b52a232cf8641b6e926eaf7b8 100644 (file)
 
 extern int DEBUGLEVEL;
 
+/****************************************************************************
+open the msrpcent sockets
+****************************************************************************/
+static BOOL ncalrpc_l_connect(struct msrpc_local *msrpc, const char *pipe_name)
+{
+        fstring path;
+        fstring pname;
+        fstrcpy(pname, pipe_name);
+        strlower(pname);
+        slprintf(path, sizeof(path) - 1, "%s/.msrpc/%s", LOCKDIR, pname);
+
+        fstrcpy(msrpc->pipe_name, pipe_name);
+
+        msrpc->fd = open_pipe_sock(path);
+
+        if (msrpc->fd == -1)
+        {
+                return False;
+        }
+
+        return True;
+}
+
 /****************************************************************************
   read an msrpc pdu from a fd. 
   The timeout is in milliseconds. 
@@ -141,6 +164,46 @@ static void ncalrpc_l_close_socket(struct msrpc_local *msrpc)
         msrpc->fd = -1;
 }
 
+static BOOL ncalrpc_l_authenticate(struct msrpc_local *msrpc)
+{
+        int sock = msrpc->fd;
+        uint32 len;
+        char *data;
+        prs_struct ps;
+        uint32 status;
+
+        uint16 command;
+
+        command = AGENT_CMD_CON;
+
+        if (!create_user_creds(&ps, msrpc->pipe_name, 0x0, command,
+                               msrpc->nt.key.pid, NULL))
+        {
+                DEBUG(0, ("could not parse credentials\n"));
+                close(sock);
+                return False;
+        }
+
+        len = ps.data_offset;
+        data = prs_data(&ps, 0);
+
+        SIVAL(data, 0, len);
+
+#ifdef DEBUG_PASSWORD
+        DEBUG(100, ("data len: %d\n", len));
+        dump_data(100, data, len);
+#endif
+
+        if (write_socket(sock, data, len) <= 0)
+        {
+                DEBUG(0, ("write failed\n"));
+                return False;
+        }
+        len = read_data(sock, (char*)&status, sizeof(status));
+
+        return len == sizeof(status) && status == 0x0;
+}
+
 
 /****************************************************************************
 shutdown a msrpcent structure
@@ -160,6 +223,62 @@ void ncalrpc_l_shutdown(struct msrpc_local *msrpc)
         memset(msrpc, 0, sizeof(*msrpc));
 }
 
+/****************************************************************************
+initialise a msrpcent structure
+****************************************************************************/
+struct msrpc_local *ncalrpc_l_initialise(struct msrpc_local *msrpc,
+                                         const vuser_key * key)
+{
+        if (!msrpc)
+        {
+                msrpc = (struct msrpc_local *)malloc(sizeof(*msrpc));
+                if (!msrpc)
+                        return NULL;
+                ZERO_STRUCTP(msrpc);
+        }
+
+        if (msrpc->initialised)
+        {
+                ncalrpc_l_shutdown(msrpc);
+        }
+
+        ZERO_STRUCTP(msrpc);
+
+        msrpc->fd = -1;
+        msrpc->outbuf = (char *)malloc(CLI_BUFFER_SIZE + 4);
+        msrpc->inbuf = (char *)malloc(CLI_BUFFER_SIZE + 4);
+        if (!msrpc->outbuf || !msrpc->inbuf)
+        {
+                return False;
+        }
+
+        msrpc->initialised = 1;
+
+        if (key != NULL)
+        {
+                msrpc->nt.key = *key;
+        }
+        else
+        {
+                NET_USER_INFO_3 usr;
+                uid_t uid = getuid();
+                gid_t gid = getgid();
+                char *name = uidtoname(uid);
+
+                ZERO_STRUCT(usr);
+
+                msrpc->nt.key.pid = sys_getpid();
+
+#if 0  /* comment ou by JERRY */
+                msrpc->nt.key.vuid = register_vuid(msrpc->nt.key.pid,
+                                                   uid, gid,
+                                                   name, name, False, &usr);
+#endif /* comment ou by JERRY */
+        }
+
+        return msrpc;
+}
+
 
 /****************************************************************************
 open the msrpcent sockets
@@ -433,3 +552,48 @@ BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
        return True;
 }
 
+/****************************************************************************
+establishes a connection right up to doing tconX, reading in a password.
+****************************************************************************/
+BOOL ncalrpc_l_establish_connection(struct msrpc_local *msrpc,
+                                    const char *pipe_name)
+{
+        if (strnequal("\\PIPE\\", pipe_name, 6))
+        {
+                pipe_name = &pipe_name[6];
+        }
+
+        DEBUG(5, ("ncalrpc_l_establish_connection: connecting to %s\n",
+                  pipe_name));
+
+        /* establish connection */
+
+        if (!msrpc->initialised)
+        {
+                return False;
+        }
+
+        if (msrpc->fd == -1)
+        {
+                if (!ncalrpc_l_connect(msrpc, pipe_name))
+                {
+                        DEBUG(1,
+                              ("ncalrpc_l_establish_connection: failed %s)\n",
+                               pipe_name));
+
+                        return False;
+                }
+        }
+
+        if (!ncalrpc_l_authenticate(msrpc))
+        {
+                DEBUG(0, ("authenticate failed\n"));
+                close(msrpc->fd);
+                msrpc->fd = -1;
+                return False;
+        }
+
+        return True;
+}
+
+
index 1c13ff2758e5b9c18c1201baebcb594e133660d7..42f1dc0644aef1374cec7c454602964e0f7b51c0 100644 (file)
@@ -221,6 +221,52 @@ char *dos_unistr2_to_str(UNISTR2 *str)
        return lbuf;
 }
 
+/*******************************************************************
+ Put an ASCII string into a UNICODE array (uint16's).
+ ********************************************************************/
+void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
+{
+        uint16 *destend = dest + maxlen;
+        register char c;
+
+        while (dest < destend)
+        {
+                c = *(src++);
+                if (c == 0)
+                {
+                        break;
+                }
+
+                *(dest++) = (uint16)c;
+        }
+
+        *dest = 0;
+}
+
+
+/*******************************************************************
+ Pull an ASCII string out of a UNICODE array (uint16's).
+ ********************************************************************/
+
+void unistr_to_ascii(char *dest, const uint16 *src, int len)
+{
+        char *destend = dest + len;
+        register uint16 c;
+
+        while (dest < destend)
+        {
+                c = *(src++);
+                if (c == 0)
+                {
+                        break;
+                }
+
+                *(dest++) = (char)c;
+        }
+
+        *dest = 0;
+}
+
 /*******************************************************************
  Convert a UNISTR2 structure to an ASCII string
  Warning: this version does DOS codepage.
index b546e1e4ec97353d648fd7ac7535671fd924a181..b18b1276c03648b08c71cd9b567114112ad9a3e6 100644 (file)
@@ -640,7 +640,7 @@ BOOL cli_establish_connection(struct cli_state *cli,
        {
                DEBUG(1,("failed negprot\n"));
                if (do_shutdown)
-          cli_shutdown(cli);
+                       cli_shutdown(cli);
                return False;
        }
 
@@ -707,10 +707,20 @@ BOOL cli_establish_connection(struct cli_state *cli,
                {
                        DEBUG(1,("failed session setup\n"));
                        if (do_shutdown)
-              cli_shutdown(cli);
+                             cli_shutdown(cli);
                        return False;
                }
 
+               DEBUG(1,("session setup ok\n"));
+    
+               if (*cli->server_domain || *cli->server_os || *cli->server_type)
+               {
+                       DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
+                            cli->server_domain,
+                            cli->server_os,
+                            cli->server_type));
+               }
+               
                if (do_tcon)
                {
                        if (!cli_send_tconX(cli, service, service_type,
index ded3e503543a8c44e0e1eade63bc28e4af983c10..6f098d74aea2e4cd2b4fc31c6103510d6f770529 100644 (file)
@@ -57,6 +57,17 @@ struct user_creds *usr_creds = NULL;
 vuser_key *user_key = NULL;
 
 extern int DEBUGLEVEL;
+extern pstring global_myname;
+cli_auth_fns cli_noauth_fns = 
+{
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL
+};
+
+
 
 
 void init_connections(void)
@@ -75,6 +86,16 @@ static void free_con_array(uint32 num_entries,
 }
 
 
+static struct cli_connection *add_con_to_array(uint32 * len,
+                                               struct cli_connection ***array,
+                                               struct cli_connection *con)
+{
+        return (struct cli_connection *)add_item_to_array(len,
+                                                          (void ***)array,
+                                                          (void *)con);
+
+}
+
 void free_connections(void)
 {
         DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
@@ -84,6 +105,128 @@ void free_connections(void)
         init_connections();
 }
 
+static struct cli_connection *cli_con_get(const char *srv_name,
+                                          const char *pipe_name,
+                                          cli_auth_fns * auth,
+                                          void *auth_creds, BOOL reuse)
+{
+        struct cli_connection *con = NULL;
+        BOOL is_new_connection = False;
+       CREDS_NT usr;
+
+        vuser_key key;
+
+        con = (struct cli_connection *)malloc(sizeof(*con));
+
+        if (con == NULL)
+        {
+                return NULL;
+        }
+
+        memset(con, 0, sizeof(*con));
+        con->type = MSRPC_NONE;
+
+        copy_user_creds(&con->usr_creds, NULL);
+        con->usr_creds.reuse = reuse;
+
+        if (srv_name != NULL)
+        {
+                con->srv_name = strdup(srv_name);
+        }
+        if (pipe_name != NULL)
+        {
+                con->pipe_name = strdup(pipe_name);
+        }
+
+#if 0   /* commented out by JERRY */
+        if (strequal(srv_name, "\\\\."))
+        {
+                con->type = MSRPC_LOCAL;
+                become_root(False);
+                con->msrpc.local = ncalrpc_l_use_add(pipe_name, user_key,
+                                                     reuse,
+                                                     &is_new_connection);
+                unbecome_root(False);
+        }
+        else
+#endif /* commented of by JERRY */
+        {
+                struct ntuser_creds *ntc = NULL;
+                if (usr_creds != NULL)
+                {
+                        ntc = &usr_creds->ntc;
+                }
+                con->type = MSRPC_SMB;
+                con->msrpc.smb =
+                        ncacn_np_use_add(pipe_name, user_key, srv_name,
+                                         ntc, reuse,
+                                         &is_new_connection);
+
+                if (con->msrpc.smb == NULL)
+                        return NULL;
+
+                key = con->msrpc.smb->smb->key;
+                con->msrpc.smb->smb->key.pid = 0;
+                con->msrpc.smb->smb->key.vuid = UID_FIELD_INVALID;
+               create_ntc_from_cli_state ( &usr, con->msrpc.smb->smb );
+                copy_nt_creds(&con->usr_creds.ntc, &usr);
+        }
+
+        if (con->msrpc.cli != NULL)
+        {
+                if (is_new_connection)
+                {
+                        con->auth_info = NULL;
+                        con->auth_creds = auth_creds;
+
+                        if (auth != NULL)
+                        {
+                                con->auth = auth;
+                        }
+                        else
+                        {
+                                con->auth = &cli_noauth_fns;
+                        }
+
+                        if (!rpc_pipe_bind(con->msrpc.smb->smb, pipe_name, global_myname))
+                        {
+                                DEBUG(0, ("rpc_pipe_bind failed\n"));
+                                cli_connection_free(con);
+                                return NULL;
+                        }
+                }
+                else
+                {
+                        con->auth_info = cli_conn_get_auth_creds(con);
+                        con->auth = cli_conn_get_authfns(con);
+                        if (con->auth_info != NULL)
+                        {
+                                DEBUG(1,("cli_con_get: TODO: auth reuse\n"));
+                                cli_connection_free(con);
+                                return NULL;
+                        }
+                        else
+                        {
+                                con->auth = &cli_noauth_fns;
+                        }
+                }
+        }
+
+        if (con->msrpc.cli == NULL)
+        {
+                cli_connection_free(con);
+                return NULL;
+        }
+
+        if (con->type == MSRPC_SMB)
+        {
+                con->msrpc.smb->smb->key = key;
+        }
+        add_con_to_array(&num_cons, &con_list, con);
+        return con;
+}
+
+
 /****************************************************************************
 terminate client connection
 ****************************************************************************/
@@ -188,3 +331,76 @@ void cli_connection_free(struct cli_connection *con)
 
         free(con);
 }
+
+void cli_connection_unlink(struct cli_connection *con)
+{
+        if (con != NULL)
+        {
+                cli_connection_free(con);
+        }
+        return;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+                         struct cli_connection **con)
+{
+        return cli_connection_init_auth(srv_name, pipe_name, con, NULL, NULL);
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+                              struct cli_connection **con,
+                              cli_auth_fns * auth, void *auth_creds)
+{
+        BOOL reuse = True;
+
+        /*
+         * allocate
+         */
+
+        DEBUG(10, ("cli_connection_init_auth: %s %s\n",
+                   srv_name != NULL ? srv_name : "<null>", pipe_name));
+
+        *con = cli_con_get(srv_name, pipe_name, auth, auth_creds, reuse);
+
+        return (*con) != NULL;
+}
+
+/****************************************************************************
+ get auth functions associated with an msrpc session.
+****************************************************************************/
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con)
+{
+        return con != NULL ? con->auth : NULL;
+}
+
+
+/****************************************************************************
+ get auth info associated with an msrpc session.
+****************************************************************************/
+void *cli_conn_get_auth_creds(struct cli_connection *con)
+{
+        return con != NULL ? con->auth_creds : NULL;
+}
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+                      prs_struct * data, prs_struct * rdata)
+{
+        BOOL ret;
+        DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
+                   op_num, data->data_offset, data->buffer_size));
+        prs_dump("in_rpcclient", (int)op_num, data);
+        prs_realloc_data(data, data->data_offset);
+        ret = rpc_api_pipe_req(con->msrpc.smb->smb, op_num, data, rdata);
+        prs_dump("out_rpcclient", (int)op_num, rdata);
+        return ret;
+}
+
index 8711ab116eef31f148d4c213e43f8320878a0007..ade31dbb5be2949cf4d7de962bb844d9aa0512cf 100644 (file)
@@ -1079,7 +1079,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
  Do an rpc bind.
 ****************************************************************************/
 
-static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name)
+BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name)
 {
        RPC_IFACE abstract;
        RPC_IFACE transfer;
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
new file mode 100644 (file)
index 0000000..22d0e8c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  Unix SMB/Netbios implementation.
+ *  Version 1.9.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tridgell              1992-2000,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *  Copyright (C) Paul Ashton                  1997-2000,
+ *  Copyright (C) Jean Francois Micouleau      1998-2000,
+ *
+ *  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"
+#include "rpc_parse.h"
+#include "rpc_client.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a SPOOLSS Enum Printers
+****************************************************************************/
+uint32 spoolss_enum_printers(uint32 flags, fstring srv_name, uint32 level,
+                             NEW_BUFFER *buffer, uint32 offered,
+                             uint32 *needed, uint32 *returned)
+{
+        prs_struct rbuf;
+        prs_struct buf;
+        SPOOL_Q_ENUMPRINTERS q_o;
+        SPOOL_R_ENUMPRINTERS r_o;
+
+        struct cli_connection *con = NULL;
+
+        if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+                return False;
+
+        prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+        prs_init(&rbuf, 0, 4, UNMARSHALL);
+
+        /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
+
+        DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n", srv_name, level));
+
+        make_spoolss_q_enumprinters(&q_o, flags, "", level, buffer, offered);
+
+        /* turn parameters into data stream */
+        if (!spoolss_io_q_enumprinters("", &q_o, &buf, 0) ) {
+                prs_free_data(&rbuf);
+                prs_free_data(&buf );
+
+                cli_connection_unlink(con);
+        }
+
+        if(!rpc_con_pipe_req(con, SPOOLSS_ENUMPRINTERS, &buf, &rbuf)) {
+                prs_free_data(&rbuf);
+                prs_free_data(&buf );
+
+                cli_connection_unlink(con);
+        }
+
+        prs_free_data(&buf );
+        ZERO_STRUCT(r_o);
+
+        buffer->prs.io=UNMARSHALL;
+        buffer->prs.data_offset=0;
+        r_o.buffer=buffer;
+
+        if(!new_spoolss_io_r_enumprinters("", &r_o, &rbuf, 0)) {
+                prs_free_data(&rbuf);
+                cli_connection_unlink(con);
+        }
+
+        *needed=r_o.needed;
+        *returned=r_o.returned;
+
+        prs_free_data(&rbuf);
+        prs_free_data(&buf );
+
+        cli_connection_unlink(con);
+
+        return r_o.status;
+}
+
index 10997f028f43cf5709e2d840d723de796bd75bcb..43f8ec8717359c0d946eae2ccbcdc6724d6ee4c9 100644 (file)
@@ -48,7 +48,8 @@ static void cli_use_free(struct cli_use *cli)
        {
                if (cli->cli->initialised)
                {
-                       cli_ulogoff(cli->cli);
+                       if (cli->cli->fd != -1)
+                               cli_ulogoff(cli->cli);
                        cli_shutdown(cli->cli);
                }
                free(cli->cli);
diff --git a/source3/rpc_client/msrpc_spoolss.c b/source3/rpc_client/msrpc_spoolss.c
new file mode 100644 (file)
index 0000000..9ff88ed
--- /dev/null
@@ -0,0 +1,221 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   NT Domain Authentication SMB / MSRPC client
+   Copyright (C) Andrew Tridgell              1994-2000
+   Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+   Copyright (C) Jean-Francois Micouleau      1999-2000
+   
+   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"
+#include "nterr.h"
+#include "rpc_parse.h"
+#include "rpc_client.h"
+#include "rpcclient.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+extern struct user_creds *usr_creds;
+
+static void init_buffer(NEW_BUFFER *buffer, uint32 size)
+{
+       int new_size = 0;
+
+       buffer->ptr = (size!=0)? 1:0;
+       buffer->size=size;
+       buffer->string_at_end=size;
+       prs_init(&(buffer->prs), MAX_PDU_FRAG_LEN, 4, MARSHALL);
+        new_size = MAX(size,buffer->prs.buffer_size) - MIN(size,buffer->prs.buffer_size);
+       prs_grow(&(buffer->prs), new_size);
+       buffer->prs.io=MARSHALL;
+       buffer->prs.data_offset=0;
+}
+
+static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_0 **info)
+{
+        uint32 i;
+        PRINTER_INFO_0  *inf;
+
+        inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
+
+        buffer->prs.data_offset=0;
+
+        for (i=0; i<returned; i++) {
+                new_smb_io_printer_info_0("", buffer, &(inf[i]), 0);
+        }
+
+        *info=inf;
+}
+
+static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_1 **info)
+{
+        uint32 i;
+        PRINTER_INFO_1  *inf;
+
+        inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1));
+
+        buffer->prs.data_offset=0;
+
+        for (i=0; i<returned; i++) {
+                new_smb_io_printer_info_1("", buffer, &(inf[i]), 0);
+        }
+
+        *info=inf;
+}
+
+static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_2 **info)
+{
+        uint32 i;
+        PRINTER_INFO_2  *inf;
+
+        inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2));
+
+        buffer->prs.data_offset=0;
+
+        for (i=0; i<returned; i++) {
+                new_smb_io_printer_info_2("", buffer, &(inf[i]), 0);
+        }
+
+        *info=inf;
+}
+
+static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_3 **info)
+{
+        uint32 i;
+        PRINTER_INFO_3  *inf;
+
+        inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3));
+
+        buffer->prs.data_offset=0;
+
+        for (i=0; i<returned; i++) {
+                new_smb_io_printer_info_3("", buffer, &(inf[i]), 0);
+        }
+
+        *info=inf;
+}
+
+static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_1 **info)
+{
+        uint32 i;
+        DRIVER_INFO_1 *inf;
+
+        inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1));
+
+        buffer->prs.data_offset=0;
+
+        for (i=0; i<returned; i++) {
+                new_smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
+        }
+
+        *info=inf;
+}
+
+static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_2 **info)
+{
+        uint32 i;
+        DRIVER_INFO_2 *inf;
+
+        inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2));
+
+        buffer->prs.data_offset=0;
+
+        for (i=0; i<returned; i++) {
+                new_smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
+        }
+
+        *info=inf;
+}
+
+static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_3 **info)
+{
+        uint32 i;
+        DRIVER_INFO_3 *inf;
+
+        inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3));
+
+        buffer->prs.data_offset=0;
+
+        for (i=0; i<returned; i++) {
+                new_smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
+        }
+
+        *info=inf;
+}
+
+static void decode_printerdriverdir_info_1(NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info)
+{
+/*      DRIVER_DIRECTORY_1 *inf;
+
+        inf=(DRIVER_DIRECTORY_1 *)malloc(returned*sizeof(DRIVER_DIRECTORY_1));
+*/
+        buffer->prs.data_offset=0;
+
+        new_smb_io_driverdir_1("", buffer, info, 0);
+
+/*      *info=inf;*/
+}
+
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_printers(char* srv_name, uint32 flags, uint32 level, PRINTER_INFO_CTR ctr)
+{
+       uint32 status;
+       NEW_BUFFER buffer;
+       uint32 needed;
+       uint32 returned;
+       
+       init_buffer(&buffer, 0);
+       
+       /* send a NULL buffer first */
+       status=spoolss_enum_printers(flags, srv_name, level, &buffer, 0, &needed, &returned);
+       
+       if (status==ERROR_INSUFFICIENT_BUFFER) {
+               init_buffer(&buffer, needed);
+               status=spoolss_enum_printers(flags, srv_name, level, &buffer, needed, &needed, &returned);
+       }
+       
+       report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+       
+       if (status!=NT_STATUS_NO_PROBLEMO)
+               return False;
+               
+       switch (level) {
+       case 1:
+               decode_printer_info_1(&buffer, returned, &(ctr.printers_1));
+               break;
+       case 2:
+               decode_printer_info_2(&buffer, returned, &(ctr.printers_2));
+               break;
+       case 3:
+               decode_printer_info_3(&buffer, returned, &(ctr.printers_3));
+               break;
+       }               
+
+       display_printer_info_ctr(out_hnd, ACTION_HEADER   , level, returned, ctr);
+       display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+       display_printer_info_ctr(out_hnd, ACTION_FOOTER   , level, returned, ctr);
+       return True;
+}
+
+
index e658edbd63353654d1d903354d1e59c6f8ae2c6b..12c2f2381d010629a62b2cff6591a89832197225 100644 (file)
@@ -61,6 +61,30 @@ static void ncacn_np_shutdown(struct ncacn_np *cli)
         }
 }
 
+static BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
+                                   const char *srv_name,
+                                   const struct ntuser_creds *ntc,
+                                   const char *pipe_name,
+                                   BOOL reuse)
+{
+        BOOL new_smb_conn;
+        cli->smb = cli_net_use_add(srv_name, ntc,
+                                   True, &new_smb_conn);
+        if (cli->smb == NULL)
+        {
+                return False;
+        }
+        /* if (!cli_nt_session_open(cli->smb, pipe_name, &cli->fnum))  by JERRY */
+        if (!cli_nt_session_open(cli->smb, pipe_name))
+        {
+                cli_net_use_del(srv_name, ntc, False, NULL);
+                return False;
+        }
+        fstrcpy(cli->pipe_name, pipe_name);
+        return True;
+}
+
+
 
 /****************************************************************************
 terminate client connection
@@ -80,6 +104,31 @@ static void ncacn_np_use_free(struct ncacn_np_use *cli)
         free(cli);
 }
 
+/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct ncacn_np_use *add_ncacn_np_to_array(uint32 * len,
+                                                  struct ncacn_np_use
+                                                  ***array,
+                                                  struct ncacn_np_use *cli)
+{
+        int i;
+        for (i = 0; i < num_msrpcs; i++)
+        {
+                if (msrpcs[i] == NULL)
+                {
+                        msrpcs[i] = cli;
+                        return cli;
+                }
+        }
+
+        return (struct ncacn_np_use *)add_item_to_array(len,
+                                                        (void ***)array,
+                                                        (void *)cli);
+
+}
+
+
 
 /****************************************************************************
 delete a client state
@@ -171,3 +220,233 @@ BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
         return False;
 }
 
+/****************************************************************************
+find client state.  server name, user name, domain name and password must all
+match.
+****************************************************************************/
+static struct ncacn_np_use *ncacn_np_find(const char *srv_name,
+                                          const char *pipe_name,
+                                          const vuser_key * key,
+                                          const struct ntuser_creds
+                                          *usr_creds, BOOL reuse)
+{
+        int i;
+        const char *sv_name = srv_name;
+
+        if (strnequal("\\PIPE\\", pipe_name, 6))
+        {
+                pipe_name = &pipe_name[6];
+        }
+
+        if (strnequal("\\\\", sv_name, 2))
+        {
+                sv_name = &sv_name[2];
+        }
+
+        if (usr_creds != NULL)
+        {
+                DEBUG(10, ("ncacn_np_find: %s %s %s",
+                           srv_name, usr_creds->user_name, usr_creds->domain));
+        }
+        else
+        {
+                DEBUG(10,("ncacn_np_find: %s (no creds)\n", srv_name));
+        }
+
+        if (key != NULL)
+        {
+                DEBUG(10, ("[%d,%x]", key->pid, key->vuid));
+        }
+        DEBUG(10, ("\n"));
+
+        for (i = 0; i < num_msrpcs; i++)
+        {
+                char *ncacn_np_srv_name = NULL;
+                struct ncacn_np_use *c = msrpcs[i];
+                vuser_key k;
+
+                char *ncacn_np_name = NULL;
+
+                if (c == NULL || c->cli == NULL || c->cli->smb == NULL ||
+                    c->cli->smb->fd == -1 ||
+                    !c->cli->initialised)
+                {
+                        continue;
+                }
+
+                ncacn_np_name = c->cli->pipe_name;
+                ncacn_np_srv_name = c->cli->smb->desthost;
+
+                k = c->cli->smb->key;
+
+                DEBUG(10, ("ncacn_np_find[%d]: %s %s %s %s [%d,%x]\n",
+                           i, ncacn_np_name, ncacn_np_srv_name,
+                           c->cli->smb->user_name,
+                           c->cli->smb->domain, k.pid, k.vuid));
+
+                if (strnequal("\\\\", ncacn_np_srv_name, 2))
+                {
+                        ncacn_np_srv_name = &ncacn_np_srv_name[2];
+                }
+
+                if (strnequal("\\PIPE\\", ncacn_np_name, 6))
+                {
+                        ncacn_np_name = &ncacn_np_name[6];
+                }
+
+                if (!strequal(ncacn_np_name, pipe_name))
+                {
+                        continue;
+                }
+                if (!strequal(ncacn_np_srv_name, sv_name))
+                {
+                        continue;
+                }
+                if (key != NULL && (k.pid != key->pid || k.vuid != key->vuid))
+                {
+                        continue;
+                }
+                if (usr_creds == NULL)
+                {
+                        if (reuse)
+                        {
+                                return c;
+                        }
+                        else
+                        {
+                                continue;
+                        }
+                }
+                if (!strequal
+                    (usr_creds->user_name, c->cli->smb->user_name))
+                {
+                        continue;
+                }
+                if (!reuse
+                    && !pwd_compare(&usr_creds->pwd, &c->cli->smb->pwd))
+                {
+                        DEBUG(100, ("password doesn't match\n"));
+                        continue;
+                }
+                if (usr_creds->domain[0] == 0)
+                {
+                        return c;
+                }
+                if (strequal(usr_creds->domain, c->cli->smb->domain))
+                {
+                        return c;
+                }
+        }
+
+        return NULL;
+}
+
+
+/****************************************************************************
+initialise a msrpcent structure
+****************************************************************************/
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+                                     const vuser_key * key)
+{
+        if (!msrpc)
+        {
+                msrpc = (struct ncacn_np *)malloc(sizeof(*msrpc));
+                if (!msrpc)
+                        return NULL;
+                ZERO_STRUCTP(msrpc);
+        }
+
+        if (msrpc->initialised)
+        {
+                ncacn_np_shutdown(msrpc);
+        }
+
+        ZERO_STRUCTP(msrpc);
+
+        msrpc->fnum = -1;
+        msrpc->initialised = 1;
+
+        return msrpc;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct ncacn_np_use *ncacn_np_use_get(const char *pipe_name,
+                                             const vuser_key * key)
+{
+        struct ncacn_np_use *cli =
+                (struct ncacn_np_use *)malloc(sizeof(*cli));
+
+        if (cli == NULL)
+        {
+                return NULL;
+        }
+
+        memset(cli, 0, sizeof(*cli));
+
+        cli->cli = ncacn_np_initialise(NULL, key);
+
+        if (cli->cli == NULL)
+        {
+                return NULL;
+        }
+
+        return cli;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+                                  const vuser_key * key,
+                                  const char *srv_name,
+                                  const struct ntuser_creds *ntc,
+                                  BOOL reuse, BOOL *is_new_connection)
+{
+        struct ncacn_np_use *cli;
+        DEBUG(10, ("ncacn_np_use_add: %s\n", pipe_name));
+
+        (*is_new_connection) = False;
+        cli = ncacn_np_find(srv_name, pipe_name, key, ntc, reuse);
+
+        if (cli != NULL)
+        {
+                cli->num_users++;
+                return cli->cli;
+        }
+
+        /*
+         * allocate
+         */
+
+        (*is_new_connection) = True;
+
+        cli = ncacn_np_use_get(pipe_name, key);
+
+        if (!ncacn_np_establish_connection
+            (cli->cli, srv_name, ntc, pipe_name, True))
+        {
+                DEBUG(0, ("ncacn_np_use_add: connection failed\n"));
+                cli->cli = NULL;
+                ncacn_np_use_free(cli);
+                return NULL;
+        }
+
+        if (key != NULL)
+        {
+                cli->cli->smb->key = *key;
+        }
+        else
+        {
+                cli->cli->smb->key.pid = sys_getpid();
+                cli->cli->smb->key.vuid = UID_FIELD_INVALID;
+        }
+
+        add_ncacn_np_to_array(&num_msrpcs, &msrpcs, cli);
+        cli->num_users++;
+        return cli->cli;
+}
+
+
+
index 81ade8e1a657aaaa2ccd18955754418cc817e594..c876fe4b5a6743383dec8363f20b399274956a56 100644 (file)
@@ -36,6 +36,29 @@ struct ncalrpc_use
 static struct ncalrpc_use **clis = NULL;
 static uint32 num_clis = 0;
 
+/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct ncalrpc_use *add_cli_to_array(uint32 * len,
+                                            struct ncalrpc_use ***array,
+                                            struct ncalrpc_use *cli)
+{
+        int i;
+        for (i = 0; i < num_clis; i++)
+        {
+                if (clis[i] == NULL)
+                {
+                        clis[i] = cli;
+                        return cli;
+                }
+        }
+
+        return (struct ncalrpc_use *)add_item_to_array(len,
+                                                       (void ***)array,
+                                                       (void *)cli);
+
+}
+
 /****************************************************************************
 terminate client connection
 ****************************************************************************/
@@ -53,6 +76,141 @@ static void ncalrpc_use_free(struct ncalrpc_use *cli)
         free(cli);
 }
 
+/****************************************************************************
+find client state.  server name, user name, vuid name and password must all
+match.
+****************************************************************************/
+static struct ncalrpc_use *ncalrpc_l_find(const char *pipe_name,
+                                          const vuser_key * key, BOOL reuse)
+{
+        int i;
+        vuser_key null_usr;
+
+        if (key == NULL)
+        {
+                key = &null_usr;
+                null_usr.pid = sys_getpid();
+                null_usr.vuid = UID_FIELD_INVALID;
+        }
+
+        DEBUG(10, ("ncalrpc_l_find: %s [%d,%x]\n",
+                   pipe_name, key->pid, key->vuid));
+
+        for (i = 0; i < num_clis; i++)
+        {
+                char *cli_name = NULL;
+                struct ncalrpc_use *c = clis[i];
+
+                if (c == NULL || !c->cli->initialised)
+                {
+                        continue;
+                }
+
+                cli_name = c->cli->pipe_name;
+
+                DEBUG(10, ("ncalrpc_l_find[%d]: %s [%d,%x]\n",
+                           i, cli_name,
+                           c->cli->nt.key.pid, c->cli->nt.key.vuid));
+
+                if (!strequal(cli_name, pipe_name))
+                {
+                        continue;
+                }
+                if (reuse)
+                {
+                        return c;
+                }
+                if (key->vuid == c->cli->nt.key.vuid &&
+                    key->pid == c->cli->nt.key.pid)
+                {
+                        return c;
+                }
+        }
+
+        return NULL;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct ncalrpc_use *ncalrpc_use_get(const char *pipe_name,
+                                           const vuser_key * key)
+{
+        struct ncalrpc_use *cli = (struct ncalrpc_use *)malloc(sizeof(*cli));
+
+        if (cli == NULL)
+        {
+                return NULL;
+        }
+
+        memset(cli, 0, sizeof(*cli));
+
+        cli->cli = ncalrpc_l_initialise(NULL, key);
+
+        if (cli->cli == NULL)
+        {
+                return NULL;
+        }
+
+        return cli;
+}
+
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+                                      const vuser_key * key,
+                                      BOOL reuse, BOOL *is_new)
+{
+        struct ncalrpc_use *cli;
+
+        DEBUG(10, ("ncalrpc_l_use_add\n"));
+
+        if (strnequal("\\PIPE\\", pipe_name, 6))
+        {
+                pipe_name = &pipe_name[6];
+        }
+
+        cli = ncalrpc_l_find(pipe_name, key, reuse);
+
+        if (cli != NULL)
+        {
+                cli->num_users++;
+                DEBUG(10,
+                      ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
+                (*is_new) = False;
+                return cli->cli;
+        }
+
+        /*
+         * allocate
+         */
+
+        cli = ncalrpc_use_get(pipe_name, key);
+
+        /*
+         * connect
+         */
+
+        if (!ncalrpc_l_establish_connection(cli->cli, pipe_name))
+        {
+                DEBUG(0, ("ncalrpc_l_use_add: connection failed\n"));
+                cli->cli = NULL;
+                ncalrpc_use_free(cli);
+                return NULL;
+        }
+
+        add_cli_to_array(&num_clis, &clis, cli);
+        cli->num_users++;
+
+        DEBUG(10, ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
+
+        (*is_new) = True;
+
+        return cli->cli;
+}
+
 /****************************************************************************
 delete a client state
 ****************************************************************************/
index 46fdc5b78f6281ea6e2b189f164d9c5e2d04b92f..672b9f28e06ec2316fd0996884bd298634cbf53e 100644 (file)
@@ -425,6 +425,30 @@ void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
        }
 };
 
+void create_ntc_from_cli_state (CREDS_NT *to, const struct cli_state *cli_from)
+{
+       /* 
+        * NULL credentials -- 
+        * if this gets executed, it is a programming error.
+         * fall through to copy_nt_creds() 
+         */
+        if (cli_from == NULL)
+        {
+               copy_nt_creds (to, cli_from);
+                return;
+        }
+
+        safe_strcpy(to->domain   , cli_from->domain   , sizeof(cli_from->domain   )-1);
+        safe_strcpy(to->user_name, cli_from->user_name, sizeof(cli_from->user_name)-1);
+        memcpy(&to->pwd, &cli_from->pwd, sizeof(cli_from->pwd));
+        to->ntlmssp_flags = cli_from->ntlmssp_flags;
+        DEBUG(10,("create_ntc_fromcli_state: user %s domain %s flgs: %x\n",
+               to->user_name, to->domain,
+               to->ntlmssp_flags));
+
+};
+
+
 void copy_nt_creds(struct ntuser_creds *to,
                                const struct ntuser_creds *from)
 {
index 94a6100aa1a0a873c9159784c25ae0b98aca5eb7..3b17f51c95ca4a49a98bd7e910b4c6792224ac79 100644 (file)
@@ -26,6 +26,35 @@ extern int DEBUGLEVEL;
 #include "includes.h"
 
 
+/*******************************************************************
+ search for a memory buffer that falls within the specified offset
+ ********************************************************************/
+static const prs_struct *prs_find(const prs_struct *buf, uint32 offset)
+{
+        const prs_struct *f = NULL;
+
+#if 0          /* comment out by JERRY */
+        if (buf == NULL)
+                return False;
+
+        f = buf;
+
+        while (f != NULL && offset >= f->end)
+        {
+                DEBUG(200, ("prs_find: next[%d..%d]\n", f->start, f->end));
+
+                f = f->next;
+        }
+
+        if (f != NULL)
+        {
+                DEBUG(200, ("prs_find: found [%d..%d]\n", f->start, f->end));
+        }
+
+#endif
+        return f;
+}
+
 /*******************************************************************
 dump a prs to a file
  ********************************************************************/
@@ -63,10 +92,10 @@ void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
        DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
 }
 
+
 /*******************************************************************
  Initialise a parse structure - malloc the data if requested.
  ********************************************************************/
-
 BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io)
 {
        ZERO_STRUCTP(ps);
@@ -805,6 +834,89 @@ BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
        return True;
 }
 
+/*******************************************************************
+ frees a memory buffer.
+ ********************************************************************/
+void prs_free_data(prs_struct *buf)
+{
+        if (buf == NULL)
+                return;
+
+        if (buf->data_p != NULL)
+        {
+                free(buf->data_p);
+                buf->data_p = NULL;
+        }
+        buf->buffer_size = 0;
+}
+
+/*******************************************************************
+ reallocate a memory buffer
+********************************************************************/
+BOOL prs_realloc_data(prs_struct *buf, size_t new_size)
+{
+        char *new_data;
+
+        /* prs_sma_init();  JERRY */
+
+        prs_debug(buf, 200, "prs_realloc_data - before", "prs_realloc_data");
+
+        SMB_ASSERT(((ssize_t) new_size) >= 0);
+
+        if (new_size == 0)
+        {
+                prs_free_data(buf);
+                return True;
+        }
+
+        /* new_data = sma_realloc(prs_sma_region, buf->data_p, new_size); */
+        new_data = realloc(buf->data_p, new_size);
+
+        if (new_data != NULL)
+        {
+                if (new_size > buf->buffer_size)
+                {
+                        memset(&new_data[buf->buffer_size], 0,
+                               new_size - buf->buffer_size);
+                }
+                buf->data_p = new_data;
+                buf->buffer_size = new_size;
+        }
+        else if (buf->buffer_size >= new_size)
+        {
+                DEBUG(3, ("prs_realloc_data: warning - "
+                          "could not realloc to %d\n", new_size));
+        }
+        else
+        {
+                DEBUG(3, ("prs_realloc_data: error - "
+                          "could not realloc to %d\n", new_size));
+
+                prs_free_data(buf);
+                return False;
+        }
+
+        prs_debug(buf, 200, "prs_realloc_data - after", "prs_realloc_data");
+        return True;
+}
+
+/*******************************************************************
+ return the memory location specified by   may return NULL.
+ ********************************************************************/
+char *prs_data(const prs_struct *buf, uint32 offset)
+{
+        buf = prs_find(buf, offset);
+        if (buf != NULL)
+        {
+                /* return &(buf->data[offset - buf->start]); */
+                return &(buf->data_p[offset]);
+        }
+        return NULL;
+}
+
+
+
+
 /* useful function to store a structure in rpc wire format */
 int tdb_prs_store(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps)
 {