diff options
-rw-r--r-- | source3/include/ntdomain.h | 12 | ||||
-rw-r--r-- | source3/include/proto.h | 90 | ||||
-rw-r--r-- | source3/include/rpc_client_proto.h | 27 | ||||
-rw-r--r-- | source3/lib/cmd_interp.c | 20 | ||||
-rw-r--r-- | source3/lib/msrpc-client.c | 164 | ||||
-rw-r--r-- | source3/lib/util_unistr.c | 46 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 14 | ||||
-rw-r--r-- | source3/rpc_client/cli_connect.c | 216 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 2 | ||||
-rw-r--r-- | source3/rpc_client/cli_spoolss.c | 95 | ||||
-rw-r--r-- | source3/rpc_client/cli_use.c | 3 | ||||
-rw-r--r-- | source3/rpc_client/msrpc_spoolss.c | 221 | ||||
-rw-r--r-- | source3/rpc_client/ncacn_np_use.c | 279 | ||||
-rw-r--r-- | source3/rpc_client/ncalrpc_l_use.c | 158 | ||||
-rw-r--r-- | source3/rpc_parse/parse_creds.c | 24 | ||||
-rw-r--r-- | source3/rpc_parse/parse_prs.c | 114 |
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) { |