summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/ntdomain.h12
-rw-r--r--source3/include/proto.h90
-rw-r--r--source3/include/rpc_client_proto.h27
-rw-r--r--source3/lib/cmd_interp.c20
-rw-r--r--source3/lib/msrpc-client.c164
-rw-r--r--source3/lib/util_unistr.c46
-rw-r--r--source3/libsmb/cliconnect.c14
-rw-r--r--source3/rpc_client/cli_connect.c216
-rw-r--r--source3/rpc_client/cli_pipe.c2
-rw-r--r--source3/rpc_client/cli_spoolss.c95
-rw-r--r--source3/rpc_client/cli_use.c3
-rw-r--r--source3/rpc_client/msrpc_spoolss.c221
-rw-r--r--source3/rpc_client/ncacn_np_use.c279
-rw-r--r--source3/rpc_client/ncalrpc_l_use.c158
-rw-r--r--source3/rpc_parse/parse_creds.c24
-rw-r--r--source3/rpc_parse/parse_prs.c114
16 files changed, 1471 insertions, 14 deletions
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index 08c8163cda..ebd24c9dd6 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -37,6 +37,18 @@
* 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
{
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 1b23ba1fbc..8fcad544f4 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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
diff --git a/source3/include/rpc_client_proto.h b/source3/include/rpc_client_proto.h
index 7682057439..e3ef439804 100644
--- a/source3/include/rpc_client_proto.h
+++ b/source3/include/rpc_client_proto.h
@@ -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);
diff --git a/source3/lib/cmd_interp.c b/source3/lib/cmd_interp.c
index 7b90daa06f..f952a57e57 100644
--- a/source3/lib/cmd_interp.c
+++ b/source3/lib/cmd_interp.c
@@ -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 */
}
/****************************************************************************
diff --git a/source3/lib/msrpc-client.c b/source3/lib/msrpc-client.c
index 696413b4f9..9b9350cb7e 100644
--- a/source3/lib/msrpc-client.c
+++ b/source3/lib/msrpc-client.c
@@ -27,6 +27,29 @@
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;
+}
+
+
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 1c13ff2758..42f1dc0644 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -222,6 +222,52 @@ char *dos_unistr2_to_str(UNISTR2 *str)
}
/*******************************************************************
+ 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.
********************************************************************/
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index b546e1e4ec..b18b1276c0 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -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,
diff --git a/source3/rpc_client/cli_connect.c b/source3/rpc_client/cli_connect.c
index ded3e50354..6f098d74ae 100644
--- a/source3/rpc_client/cli_connect.c
+++ b/source3/rpc_client/cli_connect.c
@@ -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;
+}
+
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 8711ab116e..ade31dbb5b 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -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
index 0000000000..22d0e8c2b5
--- /dev/null
+++ b/source3/rpc_client/cli_spoolss.c
@@ -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;
+}
+
diff --git a/source3/rpc_client/cli_use.c b/source3/rpc_client/cli_use.c
index 10997f028f..43f8ec8717 100644
--- a/source3/rpc_client/cli_use.c
+++ b/source3/rpc_client/cli_use.c
@@ -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
index 0000000000..9ff88ed23c
--- /dev/null
+++ b/source3/rpc_client/msrpc_spoolss.c
@@ -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;
+}
+
+
diff --git a/source3/rpc_client/ncacn_np_use.c b/source3/rpc_client/ncacn_np_use.c
index e658edbd63..12c2f2381d 100644
--- a/source3/rpc_client/ncacn_np_use.c
+++ b/source3/rpc_client/ncacn_np_use.c
@@ -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;
+}
+
+
+
diff --git a/source3/rpc_client/ncalrpc_l_use.c b/source3/rpc_client/ncalrpc_l_use.c
index 81ade8e1a6..c876fe4b5a 100644
--- a/source3/rpc_client/ncalrpc_l_use.c
+++ b/source3/rpc_client/ncalrpc_l_use.c
@@ -37,6 +37,29 @@ 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
****************************************************************************/
static void ncalrpc_use_free(struct ncalrpc_use *cli)
@@ -54,6 +77,141 @@ static void ncalrpc_use_free(struct ncalrpc_use *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
****************************************************************************/
BOOL ncalrpc_l_use_del(const char *pipe_name,
diff --git a/source3/rpc_parse/parse_creds.c b/source3/rpc_parse/parse_creds.c
index 46fdc5b78f..672b9f28e0 100644
--- a/source3/rpc_parse/parse_creds.c
+++ b/source3/rpc_parse/parse_creds.c
@@ -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)
{
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 94a6100aa1..3b17f51c95 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -27,6 +27,35 @@ extern int DEBUGLEVEL;
/*******************************************************************
+ 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
********************************************************************/
void prs_dump(char *name, int v, prs_struct *ps)
@@ -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)
{