diff options
Diffstat (limited to 'source3/rpc_client/ncacn_np_use.c')
-rw-r--r-- | source3/rpc_client/ncacn_np_use.c | 279 |
1 files changed, 279 insertions, 0 deletions
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; +} + + + |