From 8d0660607f2c2d95e1319e04d0d573d9115c4dc0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 29 Nov 1999 23:56:09 +0000 Subject: this is going to sound _really_ weird, ok, but i had to implement equivalents of NetUseAdd and NetUseDel! (This used to be commit 86f4b1d3cc3887c4bb7bd6433f5f932f7db1b88e) --- source3/Makefile.in | 1 + source3/include/proto.h | 17 +- source3/libsmb/pwd_cache.c | 6 +- source3/rpc_client/cli_connect.c | 110 +++++------ source3/rpc_client/cli_netlogon_sync.c | 2 +- source3/rpc_client/cli_use.c | 330 +++++++++++++++++++++++++++++++++ 6 files changed, 397 insertions(+), 69 deletions(-) create mode 100644 source3/rpc_client/cli_use.c diff --git a/source3/Makefile.in b/source3/Makefile.in index ce0f7471e2..8f4bfbc5df 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -160,6 +160,7 @@ RPC_CLIENT_OBJ = \ rpc_client/cli_reg.o \ rpc_client/cli_pipe.o \ rpc_client/cli_connect.o \ + rpc_client/cli_use.o \ rpc_client/cli_spoolss.o \ rpc_client/cli_lsarpc.o \ rpc_client/cli_wkssvc.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index b29565f4b2..4c547be3de 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -842,7 +842,7 @@ void pwd_set_nullpwd(struct pwd_info *pwd); void pwd_set_cleartext(struct pwd_info *pwd, char *clr); void pwd_get_cleartext(struct pwd_info *pwd, char *clr); void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], const char *user, const char *server, const char *domain); @@ -1792,7 +1792,7 @@ void cli_connection_free(struct cli_connection *con); void cli_connection_unlink(struct cli_connection *con); BOOL cli_connection_init_list(char* servers, const char* pipe_name, struct cli_connection **con); -BOOL cli_connection_init(const char* server_name, const char* pipe_name, +BOOL cli_connection_init(const char* srv_name, const char* pipe_name, struct cli_connection **con); BOOL cli_connection_getsrv(const char* srv_name, const char* pipe_name, struct cli_connection **con); @@ -2161,6 +2161,19 @@ BOOL svc_change_svc_cfg( POLICY_HND *hnd, char* password, char* disp_name); +/*The following definitions come from rpc_client/cli_use.c */ + +void init_client_use(void); +void free_cli_use(void); +struct cli_state *cli_net_use_addlist(char* servers, + const struct user_credentials *usr_creds); +struct cli_state *cli_net_use_add(const char* srv_name, + const struct user_credentials *usr_creds); +BOOL cli_net_use_del(const char* srv_name, + const struct user_credentials *usr_creds, + BOOL force_close, + BOOL *connection_closed); + /*The following definitions come from rpc_client/cli_wkssvc.c */ BOOL wks_query_info( char *srv_name, uint32 switch_value, diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index b360dbd199..8f030a1a08 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -45,14 +45,14 @@ void pwd_init(struct pwd_info *pwd) /**************************************************************************** de-obfuscates a password ****************************************************************************/ -static void pwd_deobfuscate(struct pwd_info *pwd) +static void pwd_deobfuscate(const struct pwd_info *pwd) { } /**************************************************************************** obfuscates a password ****************************************************************************/ -static void pwd_obfuscate(struct pwd_info *pwd) +static void pwd_obfuscate(const struct pwd_info *pwd) { } @@ -167,7 +167,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) /**************************************************************************** gets lm and nt hashed passwords ****************************************************************************/ -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) +void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_deobfuscate(pwd); if (lm_pwd != NULL) diff --git a/source3/rpc_client/cli_connect.c b/source3/rpc_client/cli_connect.c index 6b7fba41c5..c1ec7baf12 100644 --- a/source3/rpc_client/cli_connect.c +++ b/source3/rpc_client/cli_connect.c @@ -48,6 +48,8 @@ void init_connections(void) { con_list = NULL; num_cons = 0; + + init_cli_use(); } static void free_con_array(uint32 num_entries, struct cli_connection **entries) @@ -67,9 +69,12 @@ static struct cli_connection* add_con_to_array(uint32 *len, void free_connections(void) { free_con_array(num_cons, con_list); + free_cli_use(); + + init_connections(); } -static struct cli_connection *cli_con_get(const char* srv_name, +static struct cli_connection *cli_con_getlist(char* servers, const char* pipe_name) { struct cli_connection *con = NULL; @@ -83,37 +88,57 @@ static struct cli_connection *cli_con_get(const char* srv_name, memset(con, 0, sizeof(*con)); - if (srv_name != NULL) + if (servers != NULL) { - con->srv_name = strdup(srv_name); + con->srv_name = strdup(servers); } if (pipe_name != NULL) { con->pipe_name = strdup(pipe_name); } - con->cli = cli_initialise(NULL); - con->fnum = 0xffff; - - memcpy(&con->usr_creds, usr_creds, sizeof(*usr_creds)); + con->cli = cli_net_use_addlist(servers, usr_creds); if (con->cli == NULL) { cli_connection_free(con); return NULL; } + add_con_to_array(&num_cons, &con_list, con); + return con; +} - /* - * initialise - */ +static struct cli_connection *cli_con_get(const char* srv_name, + const char* pipe_name) +{ + struct cli_connection *con = NULL; - con->cli->capabilities |= CAP_NT_SMBS | CAP_STATUS32; - cli_init_creds(con->cli, usr_creds); + con = (struct cli_connection*)malloc(sizeof(*con)); - con->cli->use_ntlmv2 = lp_client_ntlmv2(); + if (con == NULL) + { + return NULL; + } - add_con_to_array(&num_cons, &con_list, con); + memset(con, 0, sizeof(*con)); + + if (srv_name != NULL) + { + con->srv_name = strdup(srv_name); + } + if (pipe_name != NULL) + { + con->pipe_name = strdup(pipe_name); + } + con->cli = cli_net_use_add(srv_name, usr_creds); + + if (con->cli == NULL) + { + cli_connection_free(con); + return NULL; + } + add_con_to_array(&num_cons, &con_list, con); return con; } @@ -122,9 +147,12 @@ terminate client connection ****************************************************************************/ void cli_connection_free(struct cli_connection *con) { + BOOL closed; + cli_nt_session_close(con->cli, con->fnum); - cli_shutdown(con->cli); - free(con->cli); + cli_net_use_del(con->srv_name, con->usr_creds, False, NULL, &closed); + + con->cli = NULL; if (con->srv_name != NULL) { @@ -164,22 +192,13 @@ BOOL cli_connection_init_list(char* servers, const char* pipe_name, * allocate */ - *con = cli_con_get(servers, pipe_name); + *con = cli_con_getlist(servers, pipe_name); if ((*con) == NULL) { return False; } - if (!cli_connect_serverlist((*con)->cli, servers)) - { - DEBUG(0,("cli_state_init: connection failed\n")); - cli_connection_free((*con)); - return False; - } - - (*con)->cli->ntlmssp_cli_flgs = 0x0; - res = res ? cli_nt_session_open((*con)->cli, pipe_name, &(*con)->fnum) : False; @@ -189,57 +208,22 @@ BOOL cli_connection_init_list(char* servers, const char* pipe_name, /**************************************************************************** init client state ****************************************************************************/ -BOOL cli_connection_init(const char* server_name, const char* pipe_name, +BOOL cli_connection_init(const char* srv_name, const char* pipe_name, struct cli_connection **con) { - struct nmb_name calling; - struct nmb_name called; - struct in_addr *dest_ip = NULL; - fstring dest_host; - struct in_addr ip; - BOOL res = True; /* * allocate */ - *con = cli_con_get(server_name, pipe_name); + *con = cli_con_get(srv_name, pipe_name); if ((*con) == NULL) { return False; } - if (resolve_srv_name(server_name, dest_host, &ip)) - { - dest_ip = &ip; - } - else - { - return False; - } - - make_nmb_name(&called , dns_to_netbios_name(dest_host ), 32, scope); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0, scope); - - /* - * connect - */ - - if (!cli_establish_connection((*con)->cli, - dest_host, dest_ip, - &calling, &called, - "IPC$", "IPC", - False, True)) - { - DEBUG(0,("cli_state_init: connection failed\n")); - cli_connection_free((*con)); - return False; - } - - (*con)->cli->ntlmssp_cli_flgs = 0x0; - res = res ? cli_nt_session_open((*con)->cli, pipe_name, &(*con)->fnum) : False; diff --git a/source3/rpc_client/cli_netlogon_sync.c b/source3/rpc_client/cli_netlogon_sync.c index b32aaa6fa2..a56e37a8ed 100644 --- a/source3/rpc_client/cli_netlogon_sync.c +++ b/source3/rpc_client/cli_netlogon_sync.c @@ -58,7 +58,7 @@ BOOL synchronise_passdb(void) return False; } - ret = net_sam_sync(lp_password_server(), global_myname, trust_acct, + ret = net_sam_sync(lp_passwordserver(), global_myname, trust_acct, trust_passwd, hdr_deltas, deltas, &num); diff --git a/source3/rpc_client/cli_use.c b/source3/rpc_client/cli_use.c new file mode 100644 index 0000000000..d9c40139bc --- /dev/null +++ b/source3/rpc_client/cli_use.c @@ -0,0 +1,330 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + Copyright (C) Andrew Tridgell 1994-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + + 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. +*/ + +#define NO_SYSLOG + +#include "includes.h" +#include "trans2.h" + +extern int DEBUGLEVEL; +extern pstring scope; +extern pstring global_myname; + +struct cli_use +{ + struct cli_state *cli; + uint32 num_users; +}; + +static struct cli_use **clis = NULL; +uint32 num_clis = 0; + +/**************************************************************************** +terminate client connection +****************************************************************************/ +static void cli_use_free(struct cli_use *cli) +{ + cli_ulogoff(cli->cli); + cli_shutdown(cli->cli); + memset(cli->cli, 0, sizeof(*cli->cli)); + free(cli->cli); + + free(cli); +} + +/**************************************************************************** +free a client array +****************************************************************************/ +static void free_cli_array(uint32 num_entries, struct cli_use **entries) +{ + void(*fn)(void*) = (void(*)(void*))&cli_use_free; + free_void_array(num_entries, (void**)entries, *fn); +} + +/**************************************************************************** +add a client state to the array +****************************************************************************/ +static struct cli_use* add_cli_to_array(uint32 *len, + struct cli_use ***array, + struct cli_use *cli) +{ + int i; + for (i = 0; i < num_clis; i++) + { + if (clis[i] == NULL) + { + clis[i] = cli; + return cli; + } + } + + return (struct cli_use*)add_item_to_array(len, + (void***)array, (void*)cli); + +} + +/**************************************************************************** +initiate client array +****************************************************************************/ +void init_client_use(void) +{ + clis = NULL; + num_clis = 0; +} + +/**************************************************************************** +terminate client array +****************************************************************************/ +void free_cli_use(void) +{ + free_cli_array(num_clis, clis); + init_client_use(); +} + +/**************************************************************************** +find client state. server name, user name, domain name and password must all +match. +****************************************************************************/ +static struct cli_use *cli_find(const char* srv_name, + const struct user_credentials *usr_creds) +{ + int i; + const char *sv_name = srv_name; + if (strnequal("\\\\", sv_name, 2)) + { + sv_name = &sv_name[2]; + } + + for (i = 0; i < num_clis; i++) + { + uchar ntpw[16], clintpw[16]; + char *cli_name = NULL; + + if (clis[i] == NULL) continue; + + cli_name = clis[i]->cli->desthost; + if (strnequal("\\\\", cli_name, 2)) + { + cli_name = &cli_name[2]; + } + + if (!strequal(cli_name, sv_name)) continue; + + pwd_get_lm_nt_16(&usr_creds->pwd, NULL, ntpw); + pwd_get_lm_nt_16(&clis[i]->cli->usr.pwd, NULL, clintpw); + + if (strequal(usr_creds->user_name, clis[i]->cli->usr.user_name) && + strequal(usr_creds->domain, clis[i]->cli->usr.domain) && + memcmp(ntpw, clintpw, 16) == 0) + { + return clis[i]; + } + } + + return NULL; +} + +/**************************************************************************** +create a new client state from user credentials +****************************************************************************/ +static struct cli_use *cli_use_get(const char* srv_name, + const struct user_credentials *usr_creds) + +{ + struct cli_use *cli = (struct cli_use*)malloc(sizeof(*cli)); + + if (cli == NULL) + { + return NULL; + } + + memset(cli, 0, sizeof(*cli)); + + cli->cli = cli_initialise(NULL); + + if (cli->cli == NULL) + { + return NULL; + } + + cli->cli->capabilities |= CAP_NT_SMBS | CAP_STATUS32; + cli_init_creds(cli->cli, usr_creds); + + cli->cli->use_ntlmv2 = lp_client_ntlmv2(); + + add_cli_to_array(&num_clis, &clis, cli); + + return cli; +} + +/**************************************************************************** +init client state +****************************************************************************/ +struct cli_state *cli_net_use_addlist(char* servers, + const struct user_credentials *usr_creds) +{ + struct cli_use *cli = cli_find(servers, usr_creds); + + if (cli != NULL) + { + cli->num_users++; + return cli->cli; + } + + /* + * allocate + */ + + cli = cli_use_get(servers, usr_creds); + + if (cli == NULL) + { + return NULL; + } + + if (!cli_connect_serverlist(cli->cli, servers)) + { + DEBUG(0,("cli_use_init: connection failed\n")); + cli_use_free(cli); + return NULL; + } + + cli->cli->ntlmssp_cli_flgs = 0x0; + + cli->num_users++; + + return cli->cli; +} + +/**************************************************************************** +init client state +****************************************************************************/ +struct cli_state *cli_net_use_add(const char* srv_name, + const struct user_credentials *usr_creds) +{ + struct nmb_name calling; + struct nmb_name called; + struct in_addr *dest_ip = NULL; + fstring dest_host; + struct in_addr ip; + + struct cli_use *cli = cli_find(srv_name, usr_creds); + + if (cli != NULL) + { + cli->num_users++; + return cli->cli; + } + + /* + * allocate + */ + + cli = cli_use_get(srv_name, usr_creds); + + if (resolve_srv_name(srv_name, dest_host, &ip)) + { + dest_ip = &ip; + } + else + { + cli_use_free(cli); + return NULL; + } + + make_nmb_name(&called , dns_to_netbios_name(dest_host ), 32, scope); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0, scope); + + /* + * connect + */ + + if (!cli_establish_connection(cli->cli, + dest_host, dest_ip, + &calling, &called, + "IPC$", "IPC", + False, True)) + { + DEBUG(0,("cli_use_init: connection failed\n")); + cli_use_free(cli); + return NULL; + } + + cli->cli->ntlmssp_cli_flgs = 0x0; + + cli->num_users++; + + return cli->cli; +} + +/**************************************************************************** +delete a client state +****************************************************************************/ +BOOL cli_net_use_del(const char* srv_name, + const struct user_credentials *usr_creds, + BOOL force_close, + BOOL *connection_closed) +{ + int i; + const char *sv_name = srv_name; + if (strnequal("\\\\", sv_name, 2)) + { + sv_name = &sv_name[2]; + } + + *connection_closed = False; + + for (i = 0; i < num_clis; i++) + { + char *cli_name = NULL; + + if (clis[i] == NULL) continue; + if (clis[i]->cli == NULL) continue; + + cli_name = clis[i]->cli->desthost; + if (strnequal("\\\\", cli_name, 2)) + { + cli_name = &cli_name[2]; + } + + if (!strequal(cli_name, sv_name)) continue; + + if (strequal(usr_creds->user_name, + clis[i]->cli->usr.user_name) && + strequal(usr_creds->domain, + clis[i]->cli->usr.domain)) + { + /* decrement number of users */ + clis[i]->num_users--; + if (force_close || clis[i]->num_users == 0) + { + cli_use_free(clis[i]); + clis[i] = NULL; + *connection_closed = True; + } + return True; + } + } + + return False; +} + -- cgit